//pragma javascript
//pragma module NWeapon
var version = "2022-08-26";
var CommandList = [
	['nwe', '年系列装备插件'],
	['nwe reload', "重载配置文件", '<nw_0:@string=分解>'],
	['nwe give/drop gem/weapon/armor/... [物品名] [玩家名] [数量]', "获取装备", "<nw_1:@text=give;drop> <NWeaponItemType:@text=gem;rune;weapon;armor;jewelry;锻造图;宝石券;锻造石;强化石;精工石> <ItemName:@string> <Player:@target> <Count:@int>"],
	['nwe 分解', "分解手持装备", '<nw_2:@string=分解>'],
	['nwe 分解快捷栏', "分解物品快捷栏的装备", '<nw_3:@string=分解快捷栏>'],
	['nwe dz', "打开锻造界面", '<nw_4:@string=dz>'],
	['nwe show', '展示手中物品', '<nw_5:@string=show>'],
	['nwe check <attr/dz> [玩家名]', '查询我或他人的数据', '<nw_6:@string=check> <NWeaponCheckType:@text=dz;attr> [Player:@target]'],
	['nwe bind', '绑定手中装备或宝石(无法被他人使用)', '<nw_7:@string=bind>'],
	['nwe unbind [玩家名]', '解绑手中装备或宝石'],
	['nwe addnbt [代号]', '将手中物品以代号为名保存至NBT文件'],
	['nwe delnbt <代号>', '删除NBT文件中指定代号的物品'],
	['nwe seiko', '精工手中装备', '<nw_11:@string=seiko>'],
	['nwe lock', '上锁装备(不会被分解)', '<nw_12:@string=lock>'],
	['nwe unlock', '解锁装备', '<nw_13:@string=unlock>'],
	['nwe offhand', '将手持物品与副手调换', '<nw_14:@string=offhand>'],
	['nwe inlay', "装备宝石镶嵌界面", '<nw_15:@string=inlay>'],
	['nwe rune', '装备符文界面', '<nw_16:@string=rune>'],
	['nwe strengthen', '装备强化界面', '<nw_17:@string=strengthen>'],
	['nwe fixtag', '修复武器NTag解决无法精工等问题', '<nw_18:@string=fixtag>'],
	['nwe upgrade <当前装备NTag> [目标装备NTag]', '打开一个转换炉用于升级/更新装备'],
	['nwe effect <玩家名> <属性名> [值] [时长]', '给予指定玩家指定时长的属性值', '<nw_2:@text=effect> <Player:@target> <attrName:@string> [value:@int] [time:@int]'],
    ['new bore', '为手中装备打孔', '<nw_21:@string=bore>']
];
//★ ☆ ≛ ⋆ ⍟ ⍣ ★ ☆ ✡ ✦ ✧ ✪ ✫ ✬ ✨ ✯ ✰ ✴ ✵ ✶ ✷ ✸ ✹ ❂ ⭐ ⭑ ⭒ 🌟 🌠 🔯
//▲ ✶ ✹
//✶ ✸ ✹ ❂
//3 6 9 12
if (manager.readFile('./plugins/BlocklyNukkit/NWeapon/Config.yml') === "FILE NOT FOUND") {
	manager.writeFile("./plugins/BlocklyNukkit/NWeapon/Config.yml", manager.JSONtoYAML(JSON.stringify({
		"language": 'zh_cn',
		"version": version,
		"worlds-disabled": "world1, world2",
		允许附魔: false,
		NeedFailedTips: "§c=== 需求未满足 ===\n缺少：§7%1",
		品阶: [
			"§5一阶装备",
			"§5二阶装备",
			"§5三阶装备",
			"§5四阶装备",
			"§5五阶装备",
			"§3六阶装备",
			"§c魔王拆解",
			"§c幻域元素",
			"§e天族宝具",
			"§3[§e觉醒§3]§f□□□□□",
			"§3[§e觉醒§3]§b■§f□□□□",
			"§3[§e觉醒§3]§b■■§f□□□",
			"§3[§e觉醒§3]§b■■■§f□□",
			"§3[§e觉醒§3]§b■■■■§f□",
			"§3[§e觉醒§3]§b■■■■■",
			"§d§l炼化§r §f△△△",
			"§d§l炼化§r §b▲§f△△",
			"§d§l炼化§r §b▲▲§f△",
			"§d§l炼化§r §b▲▲▲",
			"§6神圣能量 §7✧✧✧",
			"§6神圣能量 §d✧§7✧✧",
			"§6神圣能量 §d✧✧§7✧",
			"§6神圣能量 §d✧✧✧",
			"§7其它"
		],
		稀有度: [
			"§b普通",
			"§a优秀",
			"§1稀有",
			"§5史诗",
			"§6传说",
			"§6§l远古传说",
			"§c幻域",
			"§l§d亚神器",
			"§3天族宝具",
			"§e定制"
		],
		分解所得: [
			{
				"code_num1": [
					"mi give",
					"mi give"
				],
				"code_num2": [
					"mi give",
					"mi give"
				]
			},
			[
				["mi give {player} 下级装备核心 1", "mi give {player} 一阶锻造材料 3"],
				["mi give {player} 下级装备核心 1", "mi give {player} 一阶锻造材料 5", "mi give {player} 二阶锻造材料 3"],
				["mi give {player} 下级装备核心 1", "mi give {player} 三阶锻造材料 3", "mi give {player} 二阶锻造材料 5"],
				["mi give {player} 中级装备核心 1", "mi give {player} 四阶锻造材料 3", "mi give {player} 三阶锻造材料 5"]
			]
		],
		锻造模式: 1,
		锻造: [
			["§4逆天","§6传说","§5史诗","§9稀有","§b精良","§a优良","§7普通","§1粗糙"],
			[.001, .015, .04, .085, .109, .15, .38, .22],
			[2.75, 2.05, 1.75, 1.1, .8, .5, .3, .15]
		],
		锻造等级: {
			经验公式: "57*({等级}*{等级})+55",
			等级公式: "Math.sqrt(({经验}-55)/57)",
			最大等级: 9
		},
		默认镶嵌概率: 10,
		defaultCritMultiply: 1,
		ForingExp: {
			onlySameLevel: true,
			nonSameLevelGive: 0.1
		},
		AttrDisplayPercent: ["暴击倍率", "吸血倍率", "护甲强度", "反伤倍率", "经验加成", "暴击率", "吸血率", "破防率", "反伤率", "闪避率", "暴击抵抗", "吸血抵抗", "命中率", "伤害加成", "防御加成", "生命加成"],
		useHarmFloatWord: true,
		defaultAttr: {
			血量加成: 20
		},
		EffectSuit: {
			"新手套装:2": {
				attr: {
					血量加成: 50
				}
			}
		},
		GradeSymbol: {// 等级图标
			enable: true,
			list: [
				[9, 6, 3, 1],
				["❂", "✹", "✸", "✶"]
			]
		},
		Seiko: {// 装备精工
			enable: true,
			failedAddition: 0.05,
			needMoney: [1e5, 1e5, 1e5, 1e6, 1e6, 1e6, 1e7, 1e7, 1e7, 1e8, 1e8, 1e8],
			chance: [1, .7, .7, .7, .5, .5, .5, .3, .3, .3, .1, .1, .1],// 成功概率
			failed: [[3, .5, .15, .5, .3], [12, .5, .15, .5, .3]],// 失败掉等级及概率 [如果<设置的精工等级, 掉1级概率, 掉2级概率, ...]
			broadcastMessage: [6, "§6§l[精工系统] §r§a%p §f欧皇附体！成功打造出§e %lv §f级 %weapon §r！！"],
			attr: [// 0武器, 1护甲
				[{
					攻击力: 300
				}, {
					攻击力: 600
				}, {
					攻击力: 900
				}], [{
					防御力: 300
				}, {
					防御力: 600
				}, {
					防御力: 900
				}]
			]
		},
		bind: {
			enable: false,
			defaultBind: false
		},
		unbind: {
			enable: true,
			onlyOp: false,
			failExec: [],
			succExec: ["uie exec 解除灵魂绑定 \"%p\" true"]
		},
		Strengthen: {// 装备强化(淬炼)
			enable: true,
			failedAddition: 0.005,
			need: ["nbt@淬炼石:1||money@1e5", "nbt@淬炼石:2||money@2e5", "nbt@淬炼石:4||money@4e5"],
			chance: [.85, .8, .75],// 成功概率
			failed: [[5, 0], [16, .5, .5]],// 失败掉等级及概率 [如果<设置的强化等级, 破坏装备概率, 掉1级概率, 掉2级概率, ...]
			broadcastMessage: [6, "§c§l[淬炼系统] §r§a%p §f欧皇附体！成功打造出§e %lv §f级 %weapon §r！！"],
			style: {
				icon: "●",
				firstList: [
					"§f§l", "§f§l", "§a§l", "§a§l", "§b§l", "§b§l", "§9§l", "§9§l", "§5§l", "§5§l", "§6§l", "§6§l", "§d§l", "§d§l", "§1§l"
				]
			},
			attr: [// 0武器, 1护甲
				[{
					伤害加成: .01,
					暴击率: .01
				}, {
					伤害加成: .04,
					暴击率: .02
				}, {
					伤害加成: .09,
					暴击率: .03
				}], [{
					生命加成: .01,
					防御加成: .01
				}, {
					生命加成: .04,
					防御加成: .04
				}, {
					生命加成: .09,
					防御加成: .09
				}]
			]
		}
	})));
}
export function isExistDir(path){
	let File = Java.type('java.io.File');
	dir = new File(path);
	if (!dir.exists()) {
		dir.mkdir();
		manager.writeFile("./plugins/BlocklyNukkit/NWeapon/帮助(help).txt", "默认配置文件会过大增加插件体积。\n\r您可以加Q群 1022801913 并前往 https://gitee.com/ayear/nweapon/tree/master/NWeapon 查看。\n\r或者前往此链接下载 https://gitee.com/ayear/nweapon/repository/archive/master.zip");
	}
}
isExistDir('./plugins/BlocklyNukkit/NWeapon/Armor');
isExistDir('./plugins/BlocklyNukkit/NWeapon/Weapon');
isExistDir('./plugins/BlocklyNukkit/NWeapon/Gem');
isExistDir('./plugins/BlocklyNukkit/NWeapon/Rune');
isExistDir('./plugins/BlocklyNukkit/NWeapon/Jewelry');
isExistDir('./plugins/BlocklyNukkit/NWeapon/锻造图');
isExistDir('./plugins/BlocklyNukkit/NWeapon/OtherItem');
isExistDir('./plugins/BlocklyNukkit/NWeapon/PlayerAttrData');
manager.createConfig(manager.getFile("NWeapon", "PlayerData.json"), 2);// 创建玩家数据存储文件
manager.bStats("NWeapon", version, "Mcayear", 8611);// 插件状态接口 - bStats
const __EntityRegainHealthEvent = Java.type("cn.nukkit.event.entity.EntityRegainHealthEvent");
var RSHealthAPI = manager.getPlugin("HealthAPI") ? Java.type("healthapi.PlayerHealth") : false;// 获取血量核心插件
var NMonster, NWorldProtect, NWeaponSkill;
manager.setTimeout(function (){
	NMonster = require("NMonster") || false;// 获取 NMonster 插件
	NWorldProtect = require("NWorldProtect") || false;// 获取 NWorldProtect 插件
	NWeaponSkill = require("NWeaponSkill") || false;
}, 20);
var Config = JSON.parse(manager.YAMLtoJSON(manager.readFile("./plugins/BlocklyNukkit/NWeapon/Config.yml")));
var PlayerSmithingTempData = {};// 玩家锻造界面临时数据
var ItemTypeList = {
	"武器": "Weapon",
	"护甲": "Armor",
	"饰品": "Jewelry",
	"宝石": "Gem",
	"图纸": "Paper",
    "符文": "Rune",
	"锻造石": "FStone",// Forging Stone
	"精工石": "SeikoStone",// Seiko Stone
	"宝石券": "GemTicket",// Gem Inlay Ticket
	"强化石": "Strengthen"// Strengthen Stone
};
// 配置文件校验
if (Config.version != version) {
	Config.version.AttrDisplayPercent = ["暴击倍率", "吸血倍率", "护甲强度", "反伤倍率", "经验加成", "暴击率", "吸血率", "破防率", "反伤率", "闪避率", "暴击抵抗", "吸血抵抗", "命中率", "伤害加成", "防御加成", "生命加成", "破防攻击"];
	if (!Config.Seiko) {
		Config.Seiko = {// 装备精工
			enable: true,
			needMoney: [1e5, 1e5, 1e5, 1e6, 1e6, 1e6, 1e7, 1e7, 1e7, 1e8, 1e8, 1e8],
			chance: [1, .7, .7, .7, .5, .5, .5, .3, .3, .3, .1, .1, .1],// 成功概率
			failed: [[3, .5, .15, .5, .3], [12, .5, .15, .5, .3]],// 失败掉等级及概率 [如果<设置的精工等级, 掉1级概率, 掉2级概率, ...]
			broadcastMessage: [6, "§6§l[精工系统] §r§a%p §f欧皇附体！成功打造出§e %lv §f级 %weapon §r！！"],
			attr: [// 0武器, 1护甲
				[{
					攻击力: 300
				}, {
					攻击力: 600
				}, {
					攻击力: 900
				}], [{
					防御力: 300
				}, {
					防御力: 600
				}, {
					防御力: 900
				}]
			]
		}
	}
	if (Config.Seiko.failedAddition === undefined) {
		Config.Seiko.failedAddition = 0;
	}
	if (!Config.GradeSymbol) {
		Config.GradeSymbol = {// 等级图标
			enable: true,
			list: [
				[9, 6, 3, 1],
				["❂", "✹", "✸", "✶"]
			]
		};
	}
	if (!Config.bind) {
		Config.bind = {
			enable: false,
			defaultBind: false
		};
	}
	if (!Config.unbind) {
		Config.unbind = {// 装备解绑
			enable: true,
			onlyOp: false,
			failExec: [],
			succExec: ["uie exec 解除灵魂绑定 \"%p\" true"]
		};
	}
	if (!Config.Strengthen) {
		Config.Strengthen = {// 装备强化(淬炼)
			enable: true,
			failedAddition: 0.005,
			need: ["nbt@淬炼石:1||money@1e5", "nbt@淬炼石:2||money@2e5", "nbt@淬炼石:4||money@4e5"],
			chance: [.85, .8, .75],// 成功概率
			failed: [[5, 0], [16, .5, .5]],// 失败掉等级及概率 [如果<设置的强化等级, 破坏装备概率, 掉1级概率, 掉2级概率, ...]
			style: {
				icon: "●",
				firstList: [
					"§f§l", "§f§l", "§a§l", "§a§l", "§b§l", "§b§l", "§9§l", "§9§l", "§5§l", "§5§l", "§6§l", "§6§l", "§d§l", "§d§l", "§1§l"
				]
			},
			broadcastMessage: [6, "§c§l[淬炼系统] §r§a%p §f欧皇附体！成功打造出§e %lv §f级 %weapon §r！！"],
			attr: [// 0武器, 1护甲
				[{
					伤害加成: .01,
					暴击率: .01
				}, {
					伤害加成: .04,
					暴击率: .02
				}, {
					伤害加成: .09,
					暴击率: .03
				}], [{
					生命加成: .01,
					防御加成: .01
				}, {
					生命加成: .04,
					防御加成: .04
				}, {
					生命加成: .09,
					防御加成: .09
				}]
			]
		}
	}
	if (!Config.Strengthen.style) {
		Config.Strengthen.style = {
			icon: "●",
			firstList: [
				"§f§l", "§f§l", "§a§l", "§a§l", "§b§l", "§b§l", "§9§l", "§9§l", "§5§l", "§5§l", "§6§l", "§6§l", "§d§l", "§d§l", "§1§l"
			]
		};
	}
	if (!Config.NeedFailedTips) {
		Config.NeedFailedTips = "§c=== 需求未满足 ===\n缺少：§7%1";
	}
	if (!Config["worlds-disabled"]) {
		Config["worlds-disabled"] = "world1, world2";
	}
	if (!Config["defaultCritMultiply"]) {
		Config["defaultCritMultiply"] = 1;
	}
	if (!Config["EffectSuit"]) {
		Config["EffectSuit"] = {
			"新手套装:2": {
				"attr": {"血量加成": 50}
			}
		};
	}
	if (!Config["稀有度品阶排序"]) {// 武器和护甲的 lore 显示
		Config["稀有度品阶排序"] = false;// false 稀有度在上 品阶在下，true 相反
	}
	manager.writeFile("./plugins/BlocklyNukkit/NWeapon/Config.yml", manager.JSONtoYAML(JSON.stringify(Config)));
	if (new Date(Config.version).getTime() < new Date("2020-01-31").getTime()) {
		logger.warning("配置文件过低，无法完成自动更新 §c请手动更新配置文件§r");
	}
}
// 集中的延时任务调度
var TaskExecList = {};
/*
{timestamp: { func: function(){},args: [] }}
*/
function __NWeaponExecTaskList() {
	const nowtimestamp = new Date().getTime();
	for (let i in TaskExecList) {
		if (nowtimestamp > i) {
			let obj = TaskExecList[i];
			try {
				obj["func"].apply(this, obj["args"]);
				delete TaskExecList[i];
			} catch(err) {
				logger.info("§4NWeapon 的延时任务出现了错误, tag: "+(obj && obj["tag"])+"，timestamp: "+i);
				logger.info(err);
				delete TaskExecList[i];
			}
		}
	}
}
manager.createLoopTask("__NWeaponExecTaskList", 1);
function addTimeoutTask(timestamp, obj) {
	while (TaskExecList[timestamp]) {
		timestamp ++;
	}
	TaskExecList[timestamp] = obj;
	return timestamp;
}
manager.createConfig(manager.getFile("UseItemExec", "NbtItem.yml"), 2);
manager.createCommand(CommandList[0][0], CommandList[0][1], 'NWeaponCore');
manager.addCommandCompleter(CommandList[0][0], "default", "help");
for (let i = 1; i < CommandList.length; i++) {// 命令补全器
	if (CommandList[i][2]) {
		manager.addCommandCompleter(CommandList[0][0], CommandList[0][0]+i, CommandList[i][2]);
	}
}
var LoadFunc = Java.type("com.blocklynukkit.loader.Loader").plugin;
var PlayerData = {}, GemConfig = {}, RuneConfig = {}, WeaponConfig = {}, ArmorConfig = {}, JewelryConfig = {}, PaperConfig = {}, NbtItem = JSON.parse(manager.YAMLtoJSON(manager.readFile("./plugins/BlocklyNukkit/UseItemExec/NbtItem.yml")));
getItData();
getGemConfig();
getRuneConfig();
getWeaponConfig();
getArmorConfig();
getJewelryConfig();
getPaperConfig();
var ShowObj = {}, PlayerShowCount = {};
var seikoFailedNum = {}, strengthFailedNum = {};
function NWeaponCore(sender, args_) {
	var args = new Array();
	for (var i = 0; i<args_.length; i++) {
		args.push(args_[i]);
	}// 将Java数组转为JS数组 防止数组越界错误
	if (args.length === 0) {
		let helpStr = ['§7------ NWeapon Help ------§a'];
		for (var i = 0; i < CommandList.length; i++) {
			helpStr.push("§2/" + CommandList[i][0] + ":§f " + CommandList[i][1]);
		}
		return sender.sendMessage(helpStr.join("\n"));
	}
	switch(args[0]) {
		case "help":{
			let helpStr = ['§7------ NWeapon Help ------§a'];
			for (var i = 0; i < CommandList.length; i++) {
				helpStr.push("§2/" + CommandList[i][0] + ":§f " + CommandList[i][1]);
			}
			sender.sendMessage(helpStr.join("\n"));
			break;
		}
		case "addnbt":{
			if (!sender.isOp()) {
				return sender.sendMessage("[NWeapon] Only OP.");
			}
			let Item = blockitem.getItemInHand(sender);
			let keyName = args.length === 1 ? (Math.random()+[]).substr(2, 6) : args[1];
			NbtItem[keyName] = Item.getId()+":"+Item.getDamage()+":"+blockitem.getNBTString(Item);
			sender.sendMessage("[NWeapon] 已添加nbt: "+args[1]);
			manager.writeFile("./plugins/BlocklyNukkit/UseItemExec/NbtItem.yml", manager.JSONtoYAML(JSON.stringify(NbtItem)));
			break;
		}
		case "delnbt":{
			if (!sender.isOp()) {
				return sender.sendMessage("[NWeapon] Only OP.");
			}
			if (!NbtItem[args[1]]) {
				return sender.sendMessage("[NWeapon] "+args[1]+" §6不存在");
			}
			delete NbtItem[args[1]];
			sender.sendMessage("[NWeapon] 已删除nbt: "+args[1]);
			manager.writeFile("./plugins/BlocklyNukkit/UseItemExec/NbtItem.yml", manager.JSONtoYAML(JSON.stringify(NbtItem)));
			break;
		}
		case "分解":{
			WeaponDecomposition(sender, [blockitem.getItemInHand(sender)]);
			break;
		}
		case "分解快捷栏":{
			if (LoadFunc.callbackString("getVIPLevel", 0, sender.getName()) < 1) {
				return sender.sendMessage("[NWeapon] 快捷栏分解仅VIP可用");
			}
			let bagitems = inventory.getPlayerInv(sender);
			let itemlist = [];
			for (var i = 0; i < 9; i++) {
				let item = inventory.getInventorySlot(bagitems, i);
				if (item != null) {
					itemlist.push(item);
				}
			}
			WeaponDecomposition(sender, itemlist);
			break;
		}
		case "inlay":{
			sendGemInlayWin(sender);
			break;
		}
		case "check":{
			let p = sender.getPlayer();
			if (args.length === 3) {
				p = server.getPlayer(args[2]);
				if (p === null) {
					return sender.sendMessage("[NWeapon] 玩家§8" + args[1] + "§f不在线");
				}
			}
			if (args[1] === "dz") {
				if (!PlayerData[p.getName()]) {
					return sender.sendMessage("[NWeapon] 没有玩家§8" + p.getName() + "§f的数据");
				}
				let win = window.getCustomWindowBuilder('锻造 - 信息 - ' + p.getName()); //创建窗口
				win.buildLabel("当前等级: §a" + PlayerData[p.getName()].level);
				win.buildLabel("当前经验: §a" + PlayerData[p.getName()].exp);
				win.buildLabel("距离下一级(所需): §6" + PlayerData[p.getName()].req);
				//win.buildLabel("\n§a┏一一一一 §l已解锁的图纸§r§a 一一一一┓§r\n未知...\n§2┗一一一一 §l已解锁的图纸§r§2 一一一一┛§r");
				win.showToPlayer(sender, F(function () { })); //发送窗口
			} else if (args[1] === "attr") {
				let data = GetPlayerAttr(p, 1), str = "";
				if (!data) {
					return sender.sendMessage("[NWeapon] 没有玩家§8" + p.getName() + "§f的数据");
				}
				let win = window.getCustomWindowBuilder('玩家属性 - ' + p.getName()); //创建窗口
				for (var i in data.Main) {
					let value = valueToString(data.Main[i], i);
					if (value == "0") {
						continue;
					}
					str += " "+i+": "+value+"\n";
				}
				win.buildLabel("§l§a### 总属性§r\n"+str);
				for (var i in data) {
					if (["Effect", "EffectSuit", "Main"].indexOf(i) > -1) {
						continue;
					}
					str = "";
					for (n in data[i]) {
						let value = valueToString(data[i][n], n);
						if (value == 0) {
							continue;
						}
						str += "  "+n+": "+value+"\n";
					}
					win.buildLabel(" §a# "+i+"§r\n"+str);
				}
				str = "";
				let nowTime = (new Date().getTime()/1000).toFixed(0);
				for (var i in data.Effect) {
					str += "  "+i+" ("+(data.Effect[i].time - nowTime)+"s): "+data.Effect[i].level+"\n";
				}
				if (str) {
					win.buildLabel(" §a# 临时效果§r\n"+str);
				}
				win.showToPlayer(sender, F(function () { })); //发送窗口
			}
			break;
		}
		case "lock":{
			let item = blockitem.getItemInHand(sender);
			let name = item.getCustomName();
			if (ArmorConfig[name] || WeaponConfig[name]) {
				item.setNamedTag(item.getNamedTag().putString('lock', "1"));
				blockitem.setItemInHand(sender, item);
				sender.sendMessage("[NWeapon] "+name+" §r§a锁定成功");
			} else {
				sender.sendMessage("[NWeapon] §c不可锁定非NWeapon物品");
			}
			break;
		}
		case "unlock":{
			let item = blockitem.getItemInHand(sender);
			let name = item.getCustomName();
			if (ArmorConfig[name] || WeaponConfig[name]) {
				item.setNamedTag(item.getNamedTag().putString('lock', ""));
				blockitem.setItemInHand(sender, item);
				sender.sendMessage("[NWeapon] "+name+" §r§a解锁成功");
			} else {
				sender.sendMessage("[NWeapon] §c不可操作非NWeapon物品");
			}
			break;
		}
		case "bind":{
			let item = blockitem.getItemInHand(sender);
			let name = item.getCustomName();
			if (GemConfig[name] || WeaponConfig[name] || ArmorConfig[name]) {
				item = itemBindPlayer(item, sender, false, true);
				if (!item) {
					return sender.sendMessage("[NWeapon] §c绑定失败");
				}
				blockitem.setItemInHand(sender, item);
				sender.sendMessage("[NWeapon] §a绑定成功");
			} else {
				sender.sendMessage("[NWeapon] §c不可绑定非NWeapon物品");
			}
			break;
		}
		case "unbind":{
			if (!Config.unbind.enable) {
				return sender.sendMessage("[NWeapon] §c管理员未启用解绑系统");
			}
			let target = sender;
			let item = blockitem.getItemInHand(target);
			if (!sender.isOp()) {
				if (Config.unbind.onlyOp || args.length > 1) {
					return sender.sendMessage("[NWeapon] §cOnly OP.");
				}
				let res = itemUnbindPlayer(item, target);
				if (res) {
					blockitem.setItemInHand(target, res);
					target.sendMessage("[NWeapon] §a装备解绑成功");
					return;
				}
			} else if (args.length > 1) {
				target = server.getPlayer(args[1]);
			}
			if (target === null) {
				return sender.sendMessage("[NWeapon] §c所选玩家不在线");
			}
			const name = item.getCustomName();
			let data = GemConfig[name] || WeaponConfig[name] || ArmorConfig[name];
			if (data.不可解绑 && isPlayer(sender) && !sender.isOp()) {
				return target.sendMessage("[NWeapon] §c装备§r "+name+" §c不可解绑！");
			}
			if (data) {
				let res = itemUnbindPlayer(item, target);
				if (res) {
					blockitem.setItemInHand(target, res);
					target.sendMessage("[NWeapon] §a装备解绑成功");
					Config.unbind.succExec.forEach(function(v) {
						server.dispatchCommand(server.getConsoleSender(), v.replace("%p", target.name));
					});
					return;
				}
			}
			Config.unbind.failExec.forEach(function(v) {
				server.dispatchCommand(server.getConsoleSender(), v.replace("%p", target.name));
			});
			target.sendMessage("[NWeapon] §c装备解绑失败");
			break;
		}
		case "dz":{
			let inv = inventory.addInv(false, Java.to([], "cn.nukkit.item.Item[]"), "锻造");
			inventory.showFakeInv(sender, inv);
			break;
		}
		case "seiko":{
			if (Config.Seiko.enable) {
				sendSeikoWin(sender);
			} else {
				sender.sendMessage("[NWeapon] 管理员未启用精工系统");
			}
			break;
		}
		case "strengthen":{
			if (Config.Strengthen.enable) {
				sendStrengthenWin(sender);
			} else {
				sender.sendMessage("[NWeapon] 管理员未启用淬炼系统");
			}
			break;
		}
		case "show":{
			if (args.length === 2) {
				let data = ShowObj[args[1]];
				if (data === undefined) {
					return sender.sendMessage("[NWeapon] 不存在此id " + args[1]);
				}
				let win = window.getCustomWindowBuilder(data.player + ' 的物品展示 - ' + args[1]);
				win.buildLabel("# §6基本信息§r #");
				win.buildLabel(["物品名: " + data.name, "物品外形: " + data.id.join(":"), "物品标签: " + (data.NWeaponNameTag || "null"), "物品描述: \n" + data.lore].join("\n§r"));
				if (data.bindinfo) {
					win.buildLabel("# §2灵魂绑定§r #\n"+data.bindinfo);
				}
				if (data.forging) {
					win.buildLabel("# §a锻造数据§r #");
					let attr = data.forging.attr, str = "";;
					for(i in attr) {
						str += "\n  "+i+": "+valueToString(attr[i], i);
					}
					win.buildLabel(["锻造师: " + data.forging.info.player, "锻造师等级: " + data.forging.info.playerlv, "锻造强度: " + data.forging.info.intensity * 100 + "%", "锻造属性: "+str].join("\n§r"));
				}
				if (data.seikoinfo) {
					let type = WeaponConfig[data.name] || ArmorConfig[data.name], str = "";;
					type = type.类型 == "武器" ? 0 : 1;
					let attr =Config.Seiko.attr[type][data.seikoinfo.level - 1];
					for(i in attr) {
						str += "\n  "+i+": "+valueToString(attr[i], i);
					}
					win.buildLabel("# §6精工等级§r #\n"+data.seikoinfo.level+"级: "+getGradeSymbol.seiko(data.seikoinfo.level)+ "\n属性: "+str);
				}
				if (data.strengthen) {
					let type = WeaponConfig[data.name] || ArmorConfig[data.name], str = "";;
					type = type.类型 == "武器" ? 0 : 1;
					let attr =  Config.Strengthen.attr[type][data.strengthen.level - 1];
					for(i in attr) {
						str += "\n  "+i+": "+valueToString(attr[i], i);
					}
					let str_lv = Config.Strengthen.style.firstList[data.strengthen.level]+Array(Number(data.strengthen.level)+1).join(Config.Strengthen.style.icon)
					win.buildLabel("# §c强化等级§r #\n"+data.strengthen.level+"级: "+str_lv+ "§r\n属性: "+str);
				}
				if (data.gemlist) {
					win.buildLabel("# §b宝石数据§r #");
					let str = "§7槽位 | 镶嵌的宝石§r"
					if (data.gemlist.info) {
						for (var i = 0; i < data.gemlist.info.length; i++) {
							str += "\n" + data.gemlist.info[i] + " | " + (data.gemlist.inlay[i] || "§7未镶嵌") + "§r";
						}
					}
					win.buildLabel(str);
				}
				win.showToPlayer(sender, F(function(){}));
				return;
			}
			let vipLv = LoadFunc.callbackString("getVIPLevel", 0, sender.getName());
			if (PlayerShowCount[sender.name] > vipLv) {
				return sender.sendMessage("[NWeapon] 你最多只能展示" + (vipLv + 1) + "个，请隔60秒后重试");
			}
			let uid = String(Math.random()).substr(3, 3);
			let item = blockitem.getItemInHand(sender);
			let lore = blockitem.getItemLore(item).replace(/;/g, "\n");
			if (item.getId() == 0) return sender.sendMessage("[NWeapon] 你分享了份空气 : )");
			ShowObj[uid] = { player: sender.getName(), name: item.getCustomName() || item.getName(), NWeaponNameTag: item.getNamedTag() ? item.getNamedTag().getString('NWeaponNameTag') : "", id: [item.getId(), item.getDamage()], lore: lore };
			let gemlist = forging = bindinfo = seikoinfo = strengthen = undefined;
			if (item.getNamedTag()) {
				gemlist = item.getNamedTag().getString('GemList');
				if (gemlist) {
					ShowObj[uid]["gemlist"] = JSON.parse(gemlist);
				}
				forging = item.getNamedTag().getString('forging');
				if (forging) {
					ShowObj[uid]["forging"] = JSON.parse(forging);
				}
				bindinfo = item.getNamedTag().getString('PlayerBind');
				if (bindinfo) {
					ShowObj[uid]["bindinfo"] = JSON.parse(bindinfo).name;
				}
				seikoinfo = item.getNamedTag().getString('Seiko');
				if (seikoinfo) {
					ShowObj[uid]["seikoinfo"] = JSON.parse(seikoinfo);
				}
				strengthen = item.getNamedTag().getString('Strengthen');
				if (strengthen) {
					ShowObj[uid]["strengthen"] = JSON.parse(strengthen);
				}
			}
			server.broadcastMessage('[NWeapon] ' + ShowObj[uid].player + ' 展示了 ' + ShowObj[uid].name + ' §r使用 §7/nwe show ' + uid + ' §r可查看详细页面');
			server.dispatchCommand(sender, 'nwe show ' + uid);
			if (PlayerShowCount[ShowObj[uid].player] === undefined) {
				PlayerShowCount[ShowObj[uid].player] = 1;
			} else {
				PlayerShowCount[ShowObj[uid].player]++;
			}
			// 一分钟后销毁分享
			addTimeoutTask(new Date().getTime()+60000, {
				func: function (uid) {
					PlayerShowCount[ShowObj[uid].player]--;
					let player = server.getPlayer(ShowObj[uid].player);
					if (player != null) {
						player.sendMessage("[NWeapon] §7您分享的 " + ShowObj[uid].name + " §r- " + uid + " §7已失效.");
					}
					delete ShowObj[uid];
				},
				args: [uid]
			});
			break;
		}
		case "reload":{
			if (!sender.isOp()) {
				sender.sendMessage("[NWeapon] Only OP.");
				break;
			}
			sender.sendMessage("[NWeapon] 配置文件已重载.");
			Config = JSON.parse(manager.YAMLtoJSON(manager.readFile("./plugins/BlocklyNukkit/NWeapon/Config.yml")));
			PlayerData = {}, GemConfig = {}, RuneConfig = {}, WeaponConfig = {}, ArmorConfig = {}, JewelryConfig = {}, PaperConfig = {};
			getItData();
			getGemConfig();
            getRuneConfig();
			getWeaponConfig();
			getArmorConfig();
			getJewelryConfig();
			getPaperConfig();
			break;
		}
		case "give":
		case "drop":{
			let Player = sender.isPlayer() ? sender.getPlayer() : sender;
			if (!Player.isOp()) {
				return Player.sendMessage("[NWeapon] Only OP.");
			}
			let Item = onlyNameGetItem(args[1], args[2], args.length > 4 ? args[4] : null, Player);
			if (!Item) return;
			if (args[0] === "give") {
				if (args.length > 3) {
					let p = server.getPlayer(args[3]);
					if (p === null) {
						return Player.sendMessage("[NWeapon] 目标玩家不在线");
					}
					blockitem.addItemToPlayer(p, Item);
				} else {
					blockitem.addItemToPlayer(Player, Item);
				}
			} else if (args[0] === "drop") {
				if (args.length > 3) {
					let p = server.getPlayer(args[3]);
					if (p === null) {
						return Player.sendMessage("[NWeapon] 目标玩家不在线");
					}
					blockitem.makeDropItem(Java.type("cn.nukkit.level.Position").fromObject(manager.buildvec3(p.x, p.y, p.z), server.getLevelByName(p.getLevel().getName())), Item);
				} else {
					blockitem.makeDropItem(Player, Item);
				}
			}
			break;
		}
		case 'offhand': {
			let HandItem = inventory.getEntityItemInHand(sender);
			if (!HandItem.getNamedTag() || !HandItem.getNamedTag().getString('AllowOffhand')) {
				return sender.sendMessage("[NWeapon] "+(HandItem.getCustomName() || HandItem.getName())+" §c不可副手持有");
			}
			let OffhandItem = inventory.getEntityItemInOffHand(sender);
			inventory.setEntityItemInOffHand(sender, HandItem);
			inventory.setEntityItemInHand(sender, OffhandItem);
			sender.sendMessage("[NWeapon] "+(HandItem.getCustomName() || HandItem.getName())+" §a成功装备至副手");
			break;
		}
		case "rune": {
			let nametag = item.getNamedTag().getString('NWeaponNameTag');
			//nametag.split(";")[0]
			break;
		}
		case "effect": {
			if (!sender.isOp()) {
				return sender.sendMessage("[NWeapon] Only OP.");
			}
			let player;
			if (args.length > 1) {
				if (args[1].indexOf("\"") === 0) {
					args[1] = args[1].substr(1, args[1].length-2);
				}
				player = server.getPlayer(args[1]);
				if (player === null) {
					return sender.sendMessage("[NWeapon] §c目标玩家不在线");
				}
				if (args[0] === "clear") {
					SetPlayerAttr(player, "Effect", {id: false});
					sender.sendMessage("[NWeapon] 已清除 "+args[1]+" 的所有属性效果");
					break;
				}
				if (args.length > 3) {
					if (isNaN(args[3])) {
						args[3] = 0;
					}
					if (isNaN(args[4])) {
						args[4] = 0;
					}
				}
			} else {
				return sender.sendMessage("§c玩家名是必须的");
			}
			SetPlayerAttr(player, "Effect", {id: args[2], level: Number(args[3]), time: args[4]});
			if (args[4]) {
				sender.sendMessage("[NWeapon] 已设置 "+args[1]+" "+args[2]+" 属性效果值为 "+args[3]+ " 持续时长为 "+args[4]);
			} else {
				sender.sendMessage("[NWeapon] 已清除 "+args[1]+" 的 "+args[2]+" 属性效果");
			}
			break;
		}
		case "fixtag": {
			let handItem = blockitem.getItemInHand(sender);
			let handItemName = handItem.getCustomName();
			let handItemLore = blockitem.getItemLore(handItem);
			if (handItemName.substr(0, 2) === "§r" && handItemLore.indexOf("§r§4§l一一一一一一一一一一") > -1) {
				let data = WeaponConfig[handItemName], index = -1;
				if (data) {
					index = 0;
				} else {
					data = ArmorConfig[handItemName];
					if (data) {
						index = 1;
					}
				}
				if (data) {
					handItem.getNamedTag().putString('NWeaponNameTag', ItemTypeList[data.类型]+";"+handItemName);
					handItem.setNamedTag(handItem.getNamedTag());
					blockitem.setItemInHand(sender, handItem);
					return sender.sendMessage("[NWeapon] §a物品NTag已更新");
				} 
			}
			sender.sendMessage("[NWeapon] §c该物品无法修复NTag");
			break;
		}
		case "upgrade": {
			sendNWeaponUpgrade(sender, args);
			break;
		}
		case "skill": {
			if (!NWeaponSkill) {
				return sender.sendMessage("[NWeapon] §c未装载技能插件");
			}
			NWeaponSkill.cmdHandle(sender, args[1]);
			break;
		}
        case "bore": {
			let item = blockitem.getItemInHand(sender);
            if (!item.getCustomName() || !item.getNamedTag().getString('NWeaponNameTag')) {
                return backItem("§c非NWeapon物品");
            }
            var nTag = item.getNamedTag().getString('NWeaponNameTag').split(";");
            var index = ["Weapon", "Armor"].indexOf(nTag[0]);
            let HandItemData, HandItemName = item.getCustomName() || item.getName();
            if (index === -1) {
                return backItem("§c请在第一格放入NWeapon装备");
            } else if (index === 0) {
                HandItemData = WeaponConfig[nTag[1]];
            } else if (index === 1) {
                HandItemData = ArmorConfig[nTag[1]];
            }
            if (!HandItemData) {
                return backItem(HandItemName+" §r§c的配置文件丢失");
            }
            boreCount = HandItemData["品阶"] + 1;
            //toPerformedRuneWeapon(item, boreCount);
			break;
        }
	}
}
var UpgradePlayerTempData = {};
function sendNWeaponUpgrade(player, args) {
	args = args.slice(1);
	if (!args[0]) {
		return player.sendMessage("[NWeapon] §7/nwe upgrade <需升级的NTag> [升级至的NTag]");
	}
	if (args[1]) {
		if (!player.isOp()) {
			return player.sendMessage("[NWeapon] Not op, only allow use: §7/nwe upgrade <需升级的NTag> [升级至的NTag] [玩家名] [需求]");
		}
	} else {
		args[1] = args[0];
	}
	if (args[2]) {
		player = server.getPlayer(args[2]);
		if (player == null) {
			sender.sendMessage("nwe upgrade, player '"+args[2]+"' is offline!");
			return;
		}
	}
	if (args[0]) {
		var from = getNTagConfig(args[0]), to = getNTagConfig(args[1]);
		//if (!from) return player.sendMessage("[NWeapon] §cfrom的NTag有误");
		if (!to) {
			return player.sendMessage("[NWeapon] §cto的NTag有误");
		}
		UpgradePlayerTempData[player.name] = [args[0].split(";"), args[1].split(";"), args];

	}
	let hopperInv = [];
	hopperInv.push(blockitem.buildItem(0, 0, 0));
	let temp1 = blockitem.buildItem(160, 7, 1);
	temp1.setCustomName("§r§8分割线");
	let temp2 = blockitem.buildItem(160, 7, 1);
	temp2.setCustomName("§r§8分割线");
	blockitem.setItemLore(temp1, "§r请放入 "+args[0].split(";")[1]+ " §r至第一格");
	hopperInv.push(temp1);
	hopperInv.push(temp2);
	hopperInv.push(temp2);
	hopperInv.push(temp2);
	let inv = inventory.addHopperInv(Java.to(hopperInv, "cn.nukkit.item.Item[]"), "觉醒");
	inventory.showFakeInv(player, inv);
}
function sendSeikoWin(player) {
	let hopperInv = [];
	hopperInv.push(blockitem.buildItem(0, 0, 0));
	let temp1 = blockitem.buildItem(160, 7, 1);
	temp1.setCustomName("§r§8分割线");
	let temp2 = blockitem.buildItem(160, 7, 1);
	temp2.setCustomName("§r§8分割线");
	blockitem.setItemLore(temp1, "§r精工会大幅提升装备的基础属性\n\n§a成功晋升1级\n§c失败随机下降0~3级\n§7每3级属性大幅提升\n\n§r幸运卷等,请放在背包快捷栏");
	hopperInv.push(temp1);
	hopperInv.push(temp2);
	hopperInv.push(temp2);
	hopperInv.push(temp2);
	let inv = inventory.addHopperInv(Java.to(hopperInv, "cn.nukkit.item.Item[]"), "精工");
	inventory.showFakeInv(player, inv);
	return;
}
function sendStrengthenWin(player) {
	let hopperInv = [];
	hopperInv.push(blockitem.buildItem(0, 0, 0));
	let temp1 = blockitem.buildItem(160, 7, 1);
	temp1.setCustomName("§r§8分割线");
	let temp2 = blockitem.buildItem(160, 7, 1);
	temp2.setCustomName("§r§8分割线");
	blockitem.setItemLore(temp1, "§r淬炼会提升装备的 特殊 属性\n\n§a成功晋升1级\n§c5级后失败装备将会炸裂(消失)\n\n§r幸运卷等,请放在背包快捷栏");
	hopperInv.push(temp1);
	hopperInv.push(temp2);
	hopperInv.push(temp2);
	hopperInv.push(temp2);
	let inv = inventory.addHopperInv(Java.to(hopperInv, "cn.nukkit.item.Item[]"), "强化");
	inventory.showFakeInv(player, inv);
	return;
}
function sendGemInlayWin(player) {
	let HandItem = blockitem.getItemInHand(player);
	let HandItemName = HandItem.getCustomName();
	let HandItemData = WeaponConfig[HandItemName] || ArmorConfig[HandItemName];
	let usableList = [[], []];
	if (!HandItemData) {
		return player.sendMessage("[NWeapon] §c请手持NWeapon装备,宝石将镶嵌至手中装备");
	}
	if (HandItemData.镶嵌.length === 0) {
		return player.sendMessage("[NWeapon] 装备 "+HandItemName+" §r没有镶嵌槽数据");
	}
	let nbtObj = HandItem.getNamedTag().getString('GemList');
	if (nbtObj === '') {
		nbtObj = {info: HandItemData.镶嵌, inlay: []};
		HandItem.getNamedTag().putString('GemList', JSON.stringify(nbtObj));
		HandItem.setNamedTag(HandItem.getNamedTag());
		blockitem.setItemInHand(player, HandItem);
	} else {
		nbtObj = JSON.parse(nbtObj);
	}
	for (let i = 0; i < nbtObj.info.length; i++) {// 获取未镶嵌的宝石槽类型
		if (nbtObj.inlay[i] == null || nbtObj.inlay[i] == "") {// 判断 null & ""
			usableList[0].push(nbtObj.info[i]);
			usableList[1].push(i);
		}
	}
	let ItemList = inventory.getItemsInInv(inventory.getPlayerInv(player));
	let win = window.getCustomWindowBuilder("宝石镶嵌");
	let usableGemList = [];
	let haveGemList = [];
	for (let i = 0; i < ItemList.length; i++) {
		let data = GemConfig[ItemList[i].getCustomName()];
		if (data && usableList[0].indexOf(data.类别.replace(/§./g, "")) > -1) {
			let bind = ItemList[i].getNamedTag().getString('PlayerBind');
			if (bind && JSON.parse(bind).name != player.name) {
				continue;
			}// 检查物品绑定
			usableGemList.push(ItemList[i].getCustomName());
			ItemList[i].setCount(1);
			haveGemList.push(ItemList[i]);
		}
	}
	win.buildDropdown("选择宝石", "请选择;"+usableGemList.join(";"));
	win.showToPlayer(player, F(function (event){
		let sel = window.getEventCustomVar(event, 0, "dropdown");
		if (sel === "请选择") {
			return player.sendMessage("[NWeapon] §7未选择宝石，已取消镶嵌");
		}
		let gem = haveGemList[usableGemList.indexOf(sel)];
		if (!blockitem.hasItemToPlayer(player, gem)) {
			return player.sendMessage("[NWeapon] §c背包未携带该宝石");
		}
		if (HandItemData.不可镶嵌属性) {
			const GemData = GemConfig[gem.getCustomName()];
			if (!GemData) {
				return player.sendMessage("[NWeapon] §c未能成功获取 §r"+gem.getCustomName()+" §r§c的宝石信息");
			}
			for (let key in GemData.属性) {
				if (HandItemData.不可镶嵌属性.indexOf(key) > -1) {
					return player.sendMessage("[NWeapon] §c该装备不允许镶嵌 §r"+gem.getCustomName()+" §r§c宝石，因为含有§6 "+key+" §c属性！");
				}
			}
		}
		if (!blockitem.isSame(HandItem, blockitem.getItemInHand(player), true, true)) {
			return player.sendMessage("[NWeapon] §c手持物品发生变更");
		}
		let probability = Number(Config.默认镶嵌概率);

		let failProtect = 0;
		let luck = false;
		let bagitems = inventory.getPlayerInv(player);
		for (var i = 0; i < 9; i++) {
			let item = inventory.getInventorySlot(bagitems, i);
			if (item.getCustomName() && item.getNamedTag().getString('NWeaponNameTag')) {
				let arr = item.getNamedTag().getString('NWeaponNameTag').split(";");
				if (arr[0] === ItemTypeList["宝石券"]) {
					let count = 1;
					luck_ = item.getNamedTag().getString('Luck') || 0;
					failProtect_ = item.getNamedTag().getString('FailProtect') || 0;
					if (luck && luck_) {
						continue;
					} else if (luck_ > 0) {
						if (item.getNamedTag().getString('stacking')) {
							count = Math.ceil(1/luck_);
							if (item.getCount() < count) {
								count = item.getCount();
							}
						}
						probability += Number(luck_) * count;
						luck = true;
					}
					if (failProtect && failProtect_) {
						continue;
					} else if (failProtect_) {
						failProtect = Number(failProtect_);
					}
					item.setCount(count);
					blockitem.removeItemToPlayer(player, item);
					player.sendMessage("[NWeapon] §7你消耗了 "+item.getCustomName()+ "§r§7 *"+count);
				}
			}
		}
		if (getProbabilisticResults(probability)) {
			blockitem.setItemLore(HandItem, blockitem.getItemLore(HandItem).replace("§r§3[§7可镶嵌<" + GemConfig[sel].类别.replace(/§./g, "") + ">§3]", sel));
			let nbtObj = JSON.parse(HandItem.getNamedTag().getString('GemList'));
			nbtObj.inlay[usableList[1][usableList[0].indexOf(GemConfig[sel].类别.replace(/§./g, ""))]] = sel;
			HandItem.getNamedTag().putString('GemList', JSON.stringify(nbtObj));
			HandItem.setNamedTag(HandItem.getNamedTag());
			blockitem.setItemInHand(player, HandItem);
			blockitem.removeItemToPlayer(player, gem);
			player.sendMessage("[NWeapon] §a镶嵌成功");
		} else {
			player.sendMessage("[NWeapon] §c镶嵌失败");
			if (getProbabilisticResults(failProtect)){
				player.sendTitle("§2宝石受到保护", "");
			} else {
				blockitem.removeItemToPlayer(player, gem);
			}
		}
	}))
}
function WeaponDecomposition(player, list) {
	for (let i = 0; i < list.length; i++) {
		if (list[i].getNamedTag() == null) {
			player.sendMessage("[NWeapon] " + name + " §r不是NWeapon装备");
			continue;
		}
		const name = list[i].getCustomName() || list[i].getName(),
			obj = getNWeaponConfig(list[i].getNamedTag().getString('NWeaponNameTag'));
		if (!obj) {
			player.sendMessage("[NWeapon] " + name + " §r不是NWeapon装备");
			continue;
		}
		if (obj.不可分解) {
			player.sendMessage("[NWeapon] " + name + " §r不可分解");
			continue;
		}
		if (list[i].getNamedTag().getString('lock') != "") {
			player.sendMessage("[NWeapon] " + name + " §r已被锁定，用§7/nwe unlock§r解锁后尝试");
			continue;
		}
		if (Config.bind) {
			let bindObj = list[i].getNamedTag().getString('PlayerBind');
			if (bindObj) {
				bindObj = JSON.parse(bindObj);
				if (bindObj.name && bindObj.name != player.name) {
					player.sendMessage("[NWeapon] " + name + " §r是 "+bindObj.name+" 的灵魂绑定装备");
					continue;
				}
			}
		}
		let cmdlist1 = obj.分解所得,
			cmdlist2 = Config.分解所得[1][obj.品阶];
		if (cmdlist1) {
			cmdlist1 = Config.分解所得[0][cmdlist1];
			for (n in cmdlist1) {
				server.dispatchCommand(server.getConsoleSender(), cmdlist1[n].replace("{player}", player.name));
			}
			blockitem.removeItemToPlayer(player, list[i]);
		} else if (cmdlist2) {
			cmdlist2 = cmdlist2.split("\n");
			for (n in cmdlist2) {
				server.dispatchCommand(server.getConsoleSender(), cmdlist2[n].replace("{player}", player.name));
			}
			blockitem.removeItemToPlayer(player, list[i]);
		} else {
			player.sendMessage("[NWeapon] " + name + " §r没有分解方案");
		}
	}

}
function getAttributeMain(player) {
	let result = {};
	let ItemList = [blockitem.getItemInHand(player)];
	let inv = inventory.getPlayerInv(player);
	let SlotList = [player.getInventory().getHeldItemIndex(), 36, 37, 38, 39];
	let MergeAttrValue = function (obj, value, forging) {
		if (!forging) {
			forging = 1;
		}
		if (!obj) {
			obj = 0;
		}
		if (typeof(value) === "object") {
			if (typeof(obj) != "object") {
				obj = [obj, obj];
			}
			obj[0] += Math.ceil(value[0] * forging);
			obj[1] += Math.ceil(value[1] * forging);
		} else if (typeof(obj) === "object"){
			obj[0] += Math.ceil(value * forging);
			obj[1] += Math.ceil(value * forging);
		} else {
			obj += value * forging;
		}
		return obj;
	}
	var effectSuit = {};
	let EquipAttrCore = function (item, attrList) {
		let suitName = attrList.套装;
		if (suitName) {
			if (effectSuit[suitName]) {
				effectSuit[suitName] ++;
			} else {
				effectSuit[suitName] = 1;
			}
		}
		for (let key in attrList.属性) {
			let attr = attrList.属性[key];
			if (typeof (attr) === "string") {
				let arr = attr.split("-");
				attr = [new Number(arr[0]), new Number(arr[1])];
			}
			result[key] = MergeAttrValue(result[key], attr);
		}
		let forgingAttr = item.getNamedTag().getString('forging');
		if (forgingAttr != "") {// 锻造属性解析
			forgingAttr = JSON.parse(forgingAttr);
			for (key in forgingAttr.attr) {
				value = forgingAttr.attr[key];
				if (forgingAttr.attr[key].length === 1) {
					value = value[0];
				}
				result[key] = MergeAttrValue(result[key], value, forgingAttr.info.intensity);
			}
		}
		let gemList = item.getNamedTag().getString('GemList');
		if (gemList != "") {// 宝石属性解析
			gemList = JSON.parse(gemList);
			for (var i = 0; i < gemList.inlay.length; i++) {
				let GemData = GemConfig[gemList.inlay[i]];
				if (!GemData) {
					continue;
				}
				for (let key in GemData.属性) {
					let attr = GemData.属性[key];
					if (typeof (attr) === "string") {
						let arr = attr.split("-");
						attr = [new Number(arr[0]), new Number(arr[1])];
					}
					result[key] = MergeAttrValue(result[key], attr);
				}
			}
		}
		let seiko = item.getNamedTag().getString('Seiko');
		if (seiko != "") {// 精工属性解析
			seiko = JSON.parse(seiko);
			let type = attrList.类型 == "武器" ? 0 : 1;
			let attrdata = Config.Seiko.attr[type][seiko.level - 1];
			for (let key in attrdata) {
				let attr = attrdata[key];
				if (typeof (attr) === "string") {
					let arr = attr.split("-");
					attr = [new Number(arr[0]), new Number(arr[1])];
				}
				result[key] = MergeAttrValue(result[key], attr);
			}
		}
		let strengthen = item.getNamedTag().getString('Strengthen');
		if (strengthen != "") {// 强化属性解析
			strengthen = JSON.parse(strengthen);
			let type = attrList.类型 == "武器" ? 0 : 1;
			let attrdata = Config.Strengthen.attr[type][strengthen.level - 1];
			for (let key in attrdata) {
				let attr = attrdata[key];
				if (typeof (attr) === "string") {
					let arr = attr.split("-");
					attr = [new Number(arr[0]), new Number(arr[1])];
				}
				result[key] = MergeAttrValue(result[key], attr);
			}
		}
	}
	let unavailableTips = [];
	let isChange = false;
	const funcCore = function(item, type, slot, Callback){
		if (item === false || item.getId() === 0) {
			return;
		}
		const name = item.getCustomName();
		let attr = getNWeaponConfig(type+";"+name);
		if (!attr) {
			return;
		}
		if (attr.限制等级 > player.getExperienceLevel()) {
			unavailableTips.push(name+"§r§f, 使用等级不足");
			return;
		}
		if (attr.定制者 && attr.定制者 != player.name && !player.isOp()) {
			unavailableTips.push("你不是" + name + "§r的定制者");
			return;
		}
		if (attr.生效槽 && attr.生效槽.indexOf(slot) === -1) {
			return;
		}
		if (Config.bind) {
			if(Config.bind.defaultBind) {
				let itemAfter = itemBindPlayer(item, player, true, false);
				if (itemAfter) {
					Callback(itemAfter);
				}
			}
			let bindObj = item.getNamedTag().getString('playerBind');
			if (bindObj) {
				bindObj = JSON.parse(bindObj);
				if (bindObj.name != player.name) {
					unavailableTips.push(name+"§r§f, 您不是该装备的主人");
					return;
				}
			}
		}
		if (Config.允许附魔 || blockitem.getItemEnchant(item).length == 0) {
			EquipAttrCore(item, attr);
		}
	}
	// 主手武器
	funcCore(inventory.getEntityItemInHand(player), "Weapon", player.getInventory().getHeldItemIndex(), function (itemAfter){
		inventory.setEntityItemInHand(player, itemAfter);
	});
	// 副手武器
	funcCore(inventory.getEntityItemInOffHand(player), "Weapon", null, function (itemAfter){
		inventory.setEntityItemInOffHand(player, itemAfter);
	});
	// 护甲槽 36,37,38,39
	for (let i = 36; i < 40; i++) {
		funcCore(inventory.getInventorySlot(inv, i), "Armor", i, function (itemAfter){
			inventory.editInvBySlot(inv, i, itemAfter);
			isChange = true;
		});
	}
	// 配饰槽 9 - 35
	for (let i = 9; i < 36; i++) {
		funcCore(inventory.getInventorySlot(inv, i), "Jewelry", i, function (itemAfter){
			inventory.editInvBySlot(inv, i, itemAfter);
			isChange = true;
		});
	}
	if (isChange) {
		inventory.setplayerInv(player, inv);
	}
	if (unavailableTips.length) {
		player.sendPopup("§c§l您佩戴了无法使用的装备§r：\n"+unavailableTips.join("\n"));
	}
	// 套装属性
	var eventChangeSuit = [];
	var playerAttr = database.memoryStorage.getItem("PlayerAttr");
	var MainAttrForSuit = GetPlayerAttr(player, 1).EffectSuit, hasMainAttrForSuit = [];
	if (!MainAttrForSuit) return result;
	
	var newList = [];
	for (suitName in effectSuit) {
		const suitTag = suitName +":"+ effectSuit[suitName];
		newList.push(suitTag);
		// mainAttr中不存在,添加属性
		if (MainAttrForSuit.indexOf(suitTag) === -1 && Config.EffectSuit[suitTag]) {
			hasMainAttrForSuit.push(suitTag);
			SetPlayerAttr(player, suitTag, Config.EffectSuit[suitTag].attr);
			eventChangeSuit.push("§r§f你感受到了 §l"+suitTag+ " §r§f的§d套装§f属性！");
		}
	}
	MainAttrForSuit.forEach(v => {
		// 删除属性
		if (newList.indexOf(v) === -1) {
			SetPlayerAttr(player, v, {});
			eventChangeSuit.push("§r§f§l"+v+ " §r§f套装§f属性已经流失...");
		}
	});
	MainAttrForSuit = hasMainAttrForSuit;
	database.memoryStorage.setItem("playerAttr", playerAttr);
	if (eventChangeSuit.length) {
		SetPlayerAttr(player, "EffectSuit", MainAttrForSuit);
		player.sendPopup(eventChangeSuit.join("\n"));
	}
	return result;
}
export function onlyNameGetItem(type, itemname, count, sender) {
	let obj, Item = null;
	switch(type) {
		case "护甲":
		case "防具":
		case "armor": {
			obj = ArmorConfig[itemname] || manager.readFile("./plugins/BlocklyNukkit/NWeapon/Armor/"+itemname+".yml");
			break;
		}
		case "武器":
		case "weapon": {
			obj = WeaponConfig[itemname] || manager.readFile("./plugins/BlocklyNukkit/NWeapon/Weapon/"+itemname+".yml");
			break;
		}
		case "宝石":
		case "gem": {
			obj = GemConfig[itemname] || manager.readFile("./plugins/BlocklyNukkit/NWeapon/Gem/"+itemname+".yml");
			break;
		}
		case "饰品":
		case "jewelry": {
			obj = JewelryConfig[itemname] || manager.readFile("./plugins/BlocklyNukkit/NWeapon/Jewelry/"+itemname+".yml");
			break;
		}
		case "锻造图": {
			obj = PaperConfig[itemname] || manager.readFile("./plugins/BlocklyNukkit/NWeapon/锻造图/"+itemname+".yml");
			break;
		}
		case "宝石券": 
		case "精工石": 
		case "强化石": 
		case "锻造石": {
			let file = manager.readFile("./plugins/BlocklyNukkit/NWeapon/OtherItem/"+itemname+".yml");
			if (file != "FILE NOT FOUND") {
				obj = JSON.parse(manager.YAMLtoJSON(file));
				itemname = obj.名字;
			}
			break;
		}
		default: {
			if (sender) sender.sendMessage("[NWeapon] §cUnknowed args[1]:§7 " + type);
			return null;
		}
	}
	if (obj === undefined || obj === "FILE NOT FOUND") {
		if (sender) sender.sendMessage("[NWeapon] "+type+"物品 " + itemname + " §r不存在");
		return null;
	} else {
		if (typeof (obj) === "string") {
			obj = JSON.parse(manager.YAMLtoJSON(obj));
			itemname = obj.名字;
		}
		Item = getItem(itemname, obj);
		if (typeof (Item) === "undefined") {
			if (sender) sender.sendMessage("[NWeapon] "+type+"物品 " + itemname + " §r配置文件有误");
			return null;
		}
		if (!isNaN(count)) {
			if (count > 64) {
				count = 64;
			} else if (count < 1) {
				count = 1
			}
			Item.setCount(count);
		}
	}
	return Item;
}
/**
 * 获取装备武器物品
 * @param name {string} 装备物品名字
 * @param data {object} 配置文件数据
 * @returns {item}
 */
function getItem(name, data) {
	let item = blockitem.buildItem(data.外形[0], data.外形[1], 1);
	item.setCustomName(name);
	if (data.附魔) {
		for (var i = 0; i < data.附魔.length; i++) {
			let arr = data.附魔[i].split(":");
			blockitem.addItemEnchant(item, arr[0], arr[1]);
		}
	}
	let 属性 = [];
	if (data.属性) {
		for (var i in data.属性) {
			if (typeof (data.属性[i]) == 'string' && data.属性[i].indexOf("-") > -1) {
				属性.push("§r§7" + i + ": §b" + data.属性[i]);
				continue;
			}
			if (Config.AttrDisplayPercent.indexOf(i) > -1) {
				属性.push("§r§7" + i + ": §b" + Math.round(data.属性[i]*100*10000)/10000 + "%%");
			} else {
				属性.push("§r§7" + i + ": §b" + data.属性[i]);
			}
		}
	}
	if (data.不显示属性) {
		属性 = [data.不显示属性];
	}
	let rune = "", gemInlay = "", lore = "";
	if (data.镶嵌 && data.镶嵌.length > 0) {
		gemInlay += (data.稀有度 != undefined ? ';' : '') + "§r§4§l一一一一一一一一一一";
		for (var i = 0, len = data.镶嵌.length; i < len; i++) {
			gemInlay += ";§r§3[§7可镶嵌<" + data.镶嵌[i] + ">§3]";
		}
		item.getNamedTag().putString('GemList', JSON.stringify({ info: data.镶嵌, inlay: [] }));
	}
	switch(data.类型) {
		case "武器": {
			if (Config["稀有度品阶排序"]) {
				lore = [
					data.锻造属性&&data.可副手 ? "§r§f[§b" + data.类型 + "§f]§r            §e副手武器" : "§r§f[§b" + (data.可副手 ? "副手" : "") + data.类型 + "§f]§r            " + (data.品阶 != undefined ? Config.品阶[data.品阶] : ''),
					"§r§4§l一一一一一一一一一一",
					属性.join(";"),
					"§r§4§l一一一一一一一一一一",
					"§r§8装备等级: §b" + data.限制等级 + (data.介绍 ? ";§r" + data.介绍 : ''),
					"§r" + (data.稀有度 != undefined ? Config.稀有度[data.稀有度] : '') + gemInlay
				];
			} else {// 默认
				lore = [
					data.锻造属性&&data.可副手 ? "§r§f[§b" + data.类型 + "§f]§r            §e副手武器" : "§r§f[§b" + (data.可副手 ? "副手" : "") + data.类型 + "§f]§r            " + (data.稀有度 != undefined ? Config.稀有度[data.稀有度] : ''),
					"§r§4§l一一一一一一一一一一",
					属性.join(";"),
					"§r§4§l一一一一一一一一一一",
					"§r§8装备等级: §b" + data.限制等级 + (data.介绍 ? ";§r" + data.介绍 : ''),
					"§r" + (data.品阶 != undefined ? Config.品阶[data.品阶] : '') + gemInlay
				];
			}
			if (lore[lore.length-1] === "§r") {
				lore.length = lore.length -1;
			}
			lore = lore.join(";");
			break;
		}
		case "饰品":
		case "护甲": {
			if (Config["稀有度品阶排序"]) {
				lore = [
					"§r§f[§e" + data.类型 + "§f]§r            " + (data.品阶 != undefined ? Config.品阶[data.品阶] : ''),
					"§r§4§l一一一一一一一一一一",
					属性.join(";"),
					"§r§4§l一一一一一一一一一一",
					"§r§8装备等级: §b" + data.限制等级 + (data.介绍 ? ";§r" + data.介绍 : ''),
					"§r" + (data.稀有度 != undefined ? Config.稀有度[data.稀有度] : '') + gemInlay
				];
			} else {// 默认
				lore = [
					"§r§f[§e" + data.类型 + "§f]§r            " + (data.稀有度 != undefined ? Config.稀有度[data.稀有度] : ''),
					"§r§4§l一一一一一一一一一一",
					属性.join(";"),
					"§r§4§l一一一一一一一一一一",
					"§r§8装备等级: §b" + data.限制等级 + (data.介绍 ? ";§r" + data.介绍 : ''),
					"§r" + (data.品阶 != undefined ? Config.品阶[data.品阶] : '') + gemInlay
				];
			}
			if (lore[lore.length-1] === "§r") {
				lore.length = lore.length -1;
			}
			lore = lore.join(";");
			break;
		}
		case "宝石": {
			lore = [
				"§r§f[" + data.类型 + "]§r            " + data.类别,
				属性.join(";")
			].join(";");
			break;
		}
		case "图纸": {
			lore = [
				"",
				"§r§5需要锻造师等级:§f " + data.限制等级,
				"§r" + data.介绍,
				"§r§5消耗:§f " + data.消耗
			].join(";");
			break;
		}
		case "锻造石": {
			lore = "§r" + data.介绍;
			if (data.强度) item.getNamedTag().putString('Strength', data.强度);
			break;
		}
		case "精工石": 
		case "宝石券": 
		case "强化石": {
			lore = "§r" + data.介绍;
			if (data.直升) item.getNamedTag().putString('StraightUp', data.直升);
			if (data.幸运) item.getNamedTag().putString('Luck', data.幸运);
			if (data.堆叠使用) item.getNamedTag().putString('stacking', "1");
			if (data.失败保护) item.getNamedTag().putString('FailProtect', data.失败保护);
			break;
		}
		case "符文": {
            lore = [
                "§r§7「"+data.符文+"§r§7」",
                "§r§7§l一一一一一一一一一一",
                "§r§7"+data.符文类型+"        §9"+data.类别,
                "§r§7§l一一一一一一一一一一",
				"§r" + data.介绍,
                "§r§7§l一一一一一一一一一一"
            ].join(";");
			item.getNamedTag().putString('rune', data.符文);
			item.getNamedTag().putString('runeType', data.符文类型);
			item.getNamedTag().putString('type', data.类别);
			break;
		}
	}
	if (Config.bind && Config.bind.enable && ["武器", "护甲"].indexOf(data.类型) > -1) {
		lore += "\n§r§l§2灵魂绑定§r§2:§r §7未绑定§b§i§n§d§r";
		item.getNamedTag().putString('PlayerBind', JSON.stringify({name: false, past: false}));
	}
	if (data.可副手) {
		item.getNamedTag().putByte("AllowOffhand", 1);
	}
	if (data.耐久 && data.耐久 > 1) {
		item.getNamedTag().putByte("Unbreakable", 1);
		item.getNamedTag().putInt("Unbreaking", data.耐久);
		lore += "\n§r§l§2耐久§2:§7 "+data.耐久+"/"+data.耐久+"§n§j§r";
	} else if (data.无限耐久) {
		item.getNamedTag().putByte("Unbreakable", 1);
	}
	if (data.染色) {
		blockitem.setItemColor(item, data.染色.r, data.染色.g, data.染色.b);
	}
	blockitem.setItemLore(item, lore);
	item.getNamedTag().putString('NWeaponNameTag', ItemTypeList[data.类型]+";"+name);
	item.setNamedTag(item.getNamedTag());
    if (data.可符文) {
        item = toUnperformedRuneWeapon(item);
    }
	return item;
}
// 装备灵魂解绑
function itemUnbindPlayer(item, player) {
	let name = player.name;
	let oldLore = blockitem.getItemLore(item);
	if (item.getNamedTag().getString('PlayerBind')) {
		let bindObj = JSON.parse(item.getNamedTag().getString('PlayerBind'));
		if (bindObj.name && (player.isOp() || bindObj.name === name)) {
			bindObj.past = name;
			bindObj.name = false;
			oldLore = oldLore.replace(/§r§l§2灵魂绑定§r§2:§r .+§b§i§n§d§r/, "§r§l§2灵魂绑定§r§2:§r §7未绑定§b§i§n§d§r");
			item.setNamedTag(item.getNamedTag().putString('PlayerBind', JSON.stringify(bindObj)));
		} else {
			return false;
		}
	} else {
		return false;
	}
	blockitem.setItemLore(item, oldLore);
	return item;
}
// 装备灵魂绑定
function itemBindPlayer(item, player, noTips, onlyBind) {
	let name = player.name;
	if (!item.getNamedTag().getString('PlayerBind')) {
		item.setNamedTag(item.getNamedTag().putString('PlayerBind', JSON.stringify({name: name, past: name})));
	} else {
		let bindObj = JSON.parse(item.getNamedTag().getString('PlayerBind'));
		if (bindObj.name) {
			if (!noTips) {// noTips 为 true 时,不提示装备已被绑定
				player.sendMessage("[NWeapon] §c该装备已被绑定");
			}
			return false;
		}
		if (!bindObj.past) {
			bindObj.past = name;
		} else {
			if (!onlyBind) return;
		}
		bindObj.name = name;
		item.setNamedTag(item.getNamedTag().putString('PlayerBind', JSON.stringify(bindObj)));
	}
	let bindStr = "§a"+name+"§b§i§n§d§r";
	let oldLore = blockitem.getItemLore(item);
	if (!oldLore || oldLore.indexOf("§r§l§2灵魂绑定§r§2:§r ") === -1) {
		blockitem.setItemLore(item, oldLore+"§r§l§2灵魂绑定§r§2:§r "+bindStr);
	} else {
		blockitem.setItemLore(item, oldLore.replace(/§r§l§2灵魂绑定§r§2:§r .+§b§i§n§d§r/, "§r§l§2灵魂绑定§r§2:§r "+bindStr));
	}
	return item;
}
// 读取玩家&NBT物品数据
function getItData() {
	PlayerData = JSON.parse(manager.readFile("./plugins/BlocklyNukkit/NWeapon/PlayerData.json"));
	NbtItem = JSON.parse(manager.YAMLtoJSON(manager.readFile("./plugins/BlocklyNukkit/UseItemExec/NbtItem.yml")));
}
// 读取宝石配置文件
function getGemConfig() {
	let File = Java.type('java.io.File'), trdir = new File('./plugins/BlocklyNukkit/NWeapon/Gem'), trdirl = trdir.listFiles();
	for (var i = 0; i < trdirl.length; i++) {
		let f = trdirl[i];
		let temp = JSON.parse(manager.YAMLtoJSON(manager.readFile(new String(f))));
		for (k in temp.属性) if (temp.属性[k] === 0) delete temp.属性[k];
		GemConfig[temp.名字] = temp;
		if (temp.添加到创造背包) blockitem.addToCreativeBar(getItem(temp.名字, temp));
		delete GemConfig[temp.名字].名字;
	}
	logger.info('读取了 ' + trdirl.length + ' 个 宝石 配置文件');
}
// 读取符文配置文件
function getRuneConfig() {
	let File = Java.type('java.io.File'), trdir = new File('./plugins/BlocklyNukkit/NWeapon/Rune'), trdirl = trdir.listFiles();
	for (var i = 0; i < trdirl.length; i++) {
		let f = trdirl[i];
		let temp = JSON.parse(manager.YAMLtoJSON(manager.readFile(new String(f))));
		for (k in temp.属性) if (temp.属性[k] === 0) delete temp.属性[k];
		RuneConfig[temp.名字] = temp;
		if (temp.添加到创造背包) blockitem.addToCreativeBar(getItem(temp.名字, temp));
		delete RuneConfig[temp.名字].名字;
	}
	logger.info('读取了 ' + trdirl.length + ' 个 符文 配置文件');
}
// 读取武器配置文件
function getWeaponConfig() {
	let File = Java.type('java.io.File'), trdir = new File('./plugins/BlocklyNukkit/NWeapon/Weapon'), trdirl = trdir.listFiles();
	for (var i = 0; i < trdirl.length; i++) {
		let f = trdirl[i];
		let temp = JSON.parse(manager.YAMLtoJSON(manager.readFile(new String(f))));
		for (k in temp.属性) if (temp.属性[k] === 0) delete temp.属性[k];
		WeaponConfig[temp.名字] = temp;
		if (temp.添加到创造背包) blockitem.addToCreativeBar(getItem(temp.名字, temp));
		delete WeaponConfig[temp.名字].名字;
	}
	logger.info('读取了 ' + trdirl.length + ' 个 武器 配置文件');
}
// 读取护甲配置文件
function getArmorConfig() {
	let File = Java.type('java.io.File'), trdir = new File('./plugins/BlocklyNukkit/NWeapon/Armor'), trdirl = trdir.listFiles();
	for (var i = 0; i < trdirl.length; i++) {
		let f = trdirl[i];
		let temp = JSON.parse(manager.YAMLtoJSON(manager.readFile(new String(f))));
		for (k in temp.属性) if (temp.属性[k] === 0) delete temp.属性[k];
		ArmorConfig[temp.名字] = temp;
		if (temp.添加到创造背包) blockitem.addToCreativeBar(getItem(temp.名字, temp));
		delete ArmorConfig[temp.名字].名字;
	}
	logger.info('读取了 ' + trdirl.length + ' 个 护甲 配置文件');
}
// 读取饰品配置文件
function getJewelryConfig() {
	let File = Java.type('java.io.File'), trdir = new File('./plugins/BlocklyNukkit/NWeapon/Jewelry'), trdirl = trdir.listFiles();
	for (var i = 0; i < trdirl.length; i++) {
		let f = trdirl[i];
		let temp = JSON.parse(manager.YAMLtoJSON(manager.readFile(new String(f))));
		for (k in temp.属性) if (temp.属性[k] === 0) delete temp.属性[k];
		JewelryConfig[temp.名字] = temp;
		if (temp.添加到创造背包) blockitem.addToCreativeBar(getItem(temp.名字, temp));
		delete JewelryConfig[temp.名字].名字;
	}
	logger.info('读取了 ' + trdirl.length + ' 个 饰品 配置文件');
}
// 读取锻造图配置文件
function getPaperConfig() {
	let File = Java.type('java.io.File'), trdir = new File('./plugins/BlocklyNukkit/NWeapon/锻造图'), trdirl = trdir.listFiles();
	for (var i = 0; i < trdirl.length; i++) {
		let f = trdirl[i];
		let temp = JSON.parse(manager.YAMLtoJSON(manager.readFile(new String(f))));
		/*if (temp.描述) {
			temp.介绍 = temp.描述;
			delete temp.描述;
			manager.writeFile("./plugins/BlocklyNukkit/NWeapon/锻造图/"+f.getName(), manager.JSONtoYAML(JSON.stringify(temp)));
			manager.writeFile("./plugins/BlocklyNukkit/NWeapon/Config.yml", manager.JSONtoYAML(JSON.stringify(Config)));
			logger.info("已自动为 "+f.getName()+" 锻造图更新描述为介绍");
		}*/
		PaperConfig[temp.名字] = temp;
		if (temp.添加到创造背包) {
			blockitem.addToCreativeBar(getItem(temp.名字, temp));
		}
		delete PaperConfig[temp.名字].名字;
	}
	logger.info('读取了 '+trdirl.length+' 个 锻造 配置文件');
}
// 手持物品变化事件
function PlayerHeldEvent(event) {
	let player = event.getPlayer();
	SetPlayerAttr(player, "装备武器", getAttributeMain(player));
}
// 自循环体 - 核心之一
function __NWeaponLoopS() {
	var PlayerList = server.getOnlinePlayers().values().toArray();
	for (let i = 0; i < PlayerList.length; i++) {
		var player = PlayerList[i];
		if (!player.isAlive()) continue;
		var addHealth = 0;
		SetPlayerAttr(player, "装备武器", getAttributeMain(player));
		const Attr = GetPlayerAttr(player);
		const maxh = Attr.血量加成 * (1 + defineData(Attr.生命加成));
		addHealth += defineData(Attr.每秒恢复);
		
		var effect;
		effect = GetPlayerAttr(player, 1).Effect;
		const nowTime =  Number((new Date().getTime()/1000).toFixed(0))+0.5;
		for (n in effect) {
			if (nowTime > effect[n].time) {
				SetPlayerAttr(player, "Effect", {id: n, level: 0, time: 0});
				continue;
			}
		}
		effect = player.getEffect(20);
		if (effect) {// 凋零每秒减 效果等级 x 1%最大生命
			addHealth -= ((effect.getAmplifier() + 1) * Math.ceil(0.01 * maxh));
		}
		effect = null;
		if (addHealth != 0) {
			player.heal(addHealth);
		}
		if (RSHealthAPI) {// 若存在血量核心
			let PlayerHealth = RSHealthAPI.getPlayerHealth(player);
			PlayerHealth.setMaxHealth("nweapon", maxh);
			const H = PlayerHealth.getHealth();
			const MaxH = PlayerHealth.getMaxHealth();
			if (H && H < MaxH && player.getHealth() === player.getMaxHealth()) {
				const num = Math.floor(40 * H / MaxH);
				player.setHealth(num);
			}
		}
	}
}
manager.createLoopTask("__NWeaponLoopS", 20);
function PlayerToggleSprintEvent(event) {// 玩家疾跑事件
	if (event.isCancelled()) return;
	let player = event.getPlayer();
	let Attr = GetPlayerAttr(player);
	let effect = player.getEffect(1);
	if (effect) {
		Attr.移速加成 += (effect.getAmplifier() + 1) * 0.04;
	}
	let speed = 0.1 + defineData(Attr.移速加成) * 0.1;
	if (event.isSprinting()) {
		speed = speed*1.3;
	}
	player.setMovementSpeed(speed.toFixed(2));
}
// 伤害事件处理 - 核心之一
var PlayerDeathData = {}, FloatTextObj = {};
function __NWeaponHandleAttack(event){
	if (event.getEventName() === "cn.nukkit.event.entity.EntityDamageEvent" || event.getEventName() === "cn.nukkit.event.entity.EntityDamageByBlockEvent") return;
	if (event.isCancelled()) {
		return;
	}
	let Wounded = event.getEntity();// 被攻击者
	let Damager = event.getDamager();// 攻击者
	// getWorldRule
	if (NWorldProtect) {
		if(isPlayer(Damager) && isPlayer(Wounded) && !NWorldProtect.getWorldRule(Wounded.getLevel().getName(), "允许PVP")) {
			return;
		}
	}
	let WoundedName = entity.getEntityName(Wounded);
	let DamagerName = entity.getEntityName(Damager);
	let WAttr = isPlayer(Wounded) ? GetPlayerAttr(Wounded) : (NMonster ? NMonster.GetMonsterAttr(entity.getEntityID(Wounded), 0, false) : {});
	let DAttr = isPlayer(Damager) ? GetPlayerAttr(Damager) : (NMonster ? NMonster.GetMonsterAttr(entity.getEntityID(Damager), 0, false) : {});
	// 实体名字格式化
	if (isPlayer(Wounded)) {
		WoundedName = Wounded.name;
	} else {
		if (WoundedName.indexOf('\n') > -1) {
			WoundedName = WoundedName.split('\n')[0];
		} else if (WoundedName.indexOf(' §r') > -1) {
			WoundedName = WoundedName.split(' §t')[0];
		}
	}
	if (isPlayer(Damager)) {
		DamagerName = Damager.name;
	} else {
		if (DamagerName.indexOf('\n')>-1) {
			DamagerName = DamagerName.split('\n')[0];
		}
	}
	// Debuff 处理
	var effect;
	effect = Damager.getEffect(18);
	if (effect && DAttr.暴击率) {// 虚弱每级减10%暴击率,暴击倍率x50%
		DAttr.暴击率 -= ((effect.getAmplifier() + 1) * 0.1);
		if(DAttr.暴击倍率) DAttr.暴击倍率 *= .5;
	}
	effect = Damager.getEffect(19);
	if (effect && DAttr.吸血率) {// 中毒每级减10%吸血率,吸血倍率x50%
		DAttr.吸血率 -= ((effect.getAmplifier() + 1) * 0.1);
		if(DAttr.吸血倍率) DAttr.吸血倍率 *= .5;
	}
	effect = null;
	// 闪避率处理
	DAttr.命中率 = defineData(DAttr.命中率);
	if (getProbabilisticResults(defineData(WAttr.闪避率)-DAttr.命中率)) {
		if (isPlayer(Wounded)) {
			entity.makeSoundToPlayer(Wounded, "GAME_PLAYER_ATTACK_NODAMAGE");
			Wounded.sendMessage("你闪避了 " + DamagerName + " §r的攻击");
		}
		if (isPlayer(Damager)) {
			entity.makeSoundToPlayer(Damager, "GAME_PLAYER_ATTACK_NODAMAGE");
			Damager.sendMessage(WoundedName + " §r闪避了你的攻击");
		}
		return event.setCancelled(true);
	}
	// 寒冰攻击 (减移动速度)
	if (getProbabilisticResults(defineData(DAttr.寒冰攻击))) {
		entity.addEntityEffect(Wounded, 2, 1, 140, 128, 128, 128);
		if (isPlayer(Damager)) {
			Damager.sendMessage(WoundedName + " §c受到了寒冰攻击！");
		}
	}
	// 烈焰攻击 (点燃)
	if (getProbabilisticResults(defineData(DAttr.烈焰攻击))) {
		Wounded.setOnFire(7);
		if (isPlayer(Damager)) {
			Damager.sendMessage(WoundedName + " §c被你点燃了！");
		}
	}
	// 血量处理
	if (RSHealthAPI && isPlayer(Wounded)) {// 若存在血量核心
		let PlayerHealth = RSHealthAPI.getPlayerHealth(Wounded);
		let MaxH = PlayerHealth.getMaxHealth();
		let H = PlayerHealth.getHealth();
		if (H > MaxH) {
			PlayerHealth.setHealth(MaxH);
		}
	} else {
		let h = Wounded.getHealth();
		let maxh = WAttr.血量加成 * (1 + defineData(WAttr.生命加成));
		Wounded.setMaxHealth(maxh);
		if (h > maxh) {
			Wounded.setHealth(maxh);
		}
	}
	
	let FinalDamage = 0;
	
	let 暴击倍率 = 0, 暴击伤害 = 0;
	if (getProbabilisticResults(DAttr.暴击率)) {
		暴击伤害 = defineData(DAttr.爆伤力);
		暴击倍率 = defineData(Config.defaultCritMultiply) + defineData(DAttr.暴击倍率) - defineData(WAttr.暴击抵抗);
		if (暴击倍率 > 0) {
			暴击伤害 += Number((defineData(DAttr.攻击力) * 暴击倍率).toFixed(2));
		}
	}
	let 攻击力 = Number((defineData(DAttr.攻击力) * (1 + defineData(DAttr.伤害加成))).toFixed(2));
	let 破防攻击 = getProbabilisticResults(DAttr.破防率) ? DAttr.破防攻击 : 0;

	let 破甲攻击 = getProbabilisticResults(DAttr.破甲率) ? DAttr.破甲攻击 : 0;
    WAttr.护甲强度 =  defineData(WAttr.护甲强度) - 破甲攻击;// todo: 未实验

	攻击力 = 攻击力 * (1 - defineData(WAttr.护甲强度) - 破防攻击);
	
	let 吸血 = 0, 吸血倍率 = 0;
	if (getProbabilisticResults(DAttr.吸血率)) {
		吸血倍率 = defineData(DAttr.吸血倍率) - defineData(WAttr.吸血抵抗);
		if (吸血倍率 > 0) {
			吸血 = Number((defineData(DAttr.吸血力) + 攻击力 * 吸血倍率).toFixed(2));
		}
	}
	
	攻击力 = Number((攻击力 + 暴击伤害 * (1 - defineData(WAttr.护甲强度))).toFixed(2));
	
	let 治疗力 = defineData(DAttr.治疗力);

	if (攻击力) {
		//[(武器攻击+其他伤害来源)*(1+伤害加成) - 防御力*(1+防御加成)]*(100%-护甲强度)+{破防攻击-[防御力*(1+防御加成)]}
		//let 伤害 = 攻击力 - (defineData(WAttr.防御力) * (1 + defineData(WAttr.防御加成)) * defineData(WAttr.护甲强度));
		let 伤害 = 攻击力 - (defineData(WAttr.防御力) * (1 + defineData(WAttr.防御加成)));
		if (伤害 < 1) {
			伤害 = 0;
		}
		伤害 += 破防攻击;
		
		// 跳砍判断
		if (Config.jumpSplit && Config.jumpSplit.enable) {
			if (!Damager.onGround) {// isPlayer(Damager)
				var addDamage = Number((伤害*0.1).toFixed(1));
			伤害 += addDamage > 3e4 ? 3e4 : addDamage;
			}
		}

		/*
		let WoundedHealth = Wounded.getHealth();
		if (RSHealthAPI && isPlayer(Wounded)) {
			let PlayerHealth = RSHealthAPI.getPlayerHealth(Wounded);
			WoundedHealth = PlayerHealth.getHealth();
			if (伤害 > WoundedHealth) {
				if (isPlayer(Damager)) {
					PlayerDeathData[Wounded.name] = [Damager.name, blockitem.getItemInHand(Damager).getCustomName()];
				}
				PlayerHealth.setHealth(0);// Error: 有报错
			} else {
				PlayerHealth.setHealth(WoundedHealth - 伤害);
			}
			event.setDamage(0);
		}*/
		FinalDamage = 伤害;
	}
	if (getProbabilisticResults(WAttr.反伤率)) {
		let 反伤 = defineData(WAttr.反伤倍率 * FinalDamage) + defineData(WAttr.反伤力);
		let WHealth = entity.getEntityHealth(Wounded);
		if (isPlayer(WHealth)) {
			let PlayerHealth = RSHealthAPI.getPlayerHealth(Wounded);
			if (RSHealthAPI) {// 血量核心
				WHealth = PlayerHealth.getHealth();
			}
		}
		// 反伤不超过受害者现有血量
		if (WHealth < 反伤) 反伤 = WHealth;
		if (isPlayer(Damager)) {
			let PlayerHealth = RSHealthAPI.getPlayerHealth(Damager);
			if (RSHealthAPI) {// 血量核心
				let H = PlayerHealth.getHealth() - 反伤;
				PlayerHealth.setHealth(H < 1 ? 0 : H);
			} else {
				let h = Damager.getHealth() - 反伤;
				Damager.setHealth(h < 1 ? 0 : h);
			}
			entity.makeSoundToPlayer(Damager, "ARMOR_EQUIP_CHAIN");
		}
	}
	if (治疗力 && isPlayer(Wounded)) {
		if (治疗力 > 0) {
			治疗力 = 0;
		}
		let WoundedHealth = Wounded.getHealth();
		let WoundedMaxHealth = Wounded.getMaxHealth();
		let PlayerHealth = RSHealthAPI.getPlayerHealth(Wounded);
		if (RSHealthAPI) {
			WoundedHealth = PlayerHealth.getHealth();
			WoundedMaxHealth = PlayerHealth.getMaxHealth();
		}
		let health = WoundedHealth - 治疗力;
		if (health > WoundedMaxHealth) {
			PlayerHealth.setHealth(WoundedMaxHealth);
		} else {
			PlayerHealth.setHealth(health);
		}
		FinalDamage = 治疗力;
		event.setDamage(0);
	}
	if (吸血) {
		let WHealth = entity.getEntityHealth(Wounded);
		if (isPlayer(WHealth)) {
			let PlayerHealth = RSHealthAPI.getPlayerHealth(Wounded);
			if (RSHealthAPI) {// 血量核心
				WHealth = PlayerHealth.getHealth();
			}
		}
		// 吸血不超过受害者现有血量
		if (WHealth < 吸血) 吸血 = WHealth;
		if (RSHealthAPI && isPlayer(Damager)) {// 若存在血量核心
			let PlayerHealth = RSHealthAPI.getPlayerHealth(Damager);
			const MaxH = PlayerHealth.getMaxHealth();
			const H = PlayerHealth.getHealth() + 吸血;
			PlayerHealth.setHealth(H > MaxH ? MaxH : H);
		} else {
			Damager.heal(吸血);
		}
		if (isPlayer(Damager)) {
			Damager.sendMessage("你已汲取对方 §c§l" + 吸血 + "§r 生命值");
		}
	}
	if (暴击伤害 > 0 && isPlayer(Damager)) {
		Damager.sendMessage("你对" + WoundedName + "§r造成了 §l" + 攻击力 + "§r 点暴击伤害");
	}
	if (Config.useHarmFloatWord && isPlayer(Damager)) {
		let location = Wounded.getLocation();
		let pos = Java.type("cn.nukkit.level.Position").fromObject(manager.buildvec3(location.x, location.y+0.7 , location.z), server.getLevelByName(Damager.getLevel().name));
		FinalDamage = (FinalDamage || event.getFinalDamage()).toFixed(2);
		if (FinalDamage < 1 && FinalDamage > -1) {// 区间(1, -1) 设置为0
			FinalDamage = 0;
		}
		if (!治疗力 && FinalDamage < 0) {// 没有治疗力但是 伤害为负 设置为0
			FinalDamage = 0;
		}
		event.setDamage(Math.floor(FinalDamage));
		if (isPlayer(Damager)) updateUnbreaking(Damager, true);
		if (isPlayer(Wounded) && FinalDamage > 0) updateUnbreaking(Wounded, false);
		if (Config.useHarmFloatWord && isPlayer(Damager)) {
			let FloatText = entity.buildVanillaNPC(pos, (FinalDamage < 0 ? "§a+" + (-FinalDamage) : "§c-" + FinalDamage), 13, 5, "FloatTextTime");
			FloatText.setScale(0);
			FloatText.setG(3);
			FloatText.start();
			let target = FloatText.getNearestPlayer();
			if (target) {
				FloatText.lookAt(target);
			}
			FloatTextObj[entity.getEntityID(FloatText)] = 10;
			FloatText.setMotion(FloatText.getLocation().getDirectionVector().multiply(-1).add(0, 0.1, 0));
		}
	}
}
manager.customEventListener("cn.nukkit.event.entity.EntityDamageByEntityEvent", "__NWeaponHandleAttack", "NORMAL");
function FloatTextTime(event) {
	let id = entity.getEntityID(event);
	let Time = FloatTextObj[id];
	if (Time > 0) {
		FloatTextObj[id]--;
	} else {
		entity.removeEntity(event);
		delete FloatTextObj[id];
	}
}
/*
 * @brief :更新实体装备的耐久
 *
 * @param Entity ent:实体对象
 * @param Blooean isDamager:是攻击者
 * @return void
 */
function updateUnbreaking(ent, isDamager) {
	if (isDamager) {
		const item = inventory.getEntityItemInHand(ent);
		if (!item.getId()) return;
		if (item.getNamedTag() === null || item.getNamedTag().getString('NWeaponNameTag') === null) return;
		const data = getNWeaponConfig(item.getNamedTag().getString('NWeaponNameTag'));
		if (!data) return;
		const item_ = setItemUnbreaking(item, data.耐久);
		if (!item_) return;
		if (item_.getNamedTag().getInt('Unbreaking') < 1) {
			inventory.setEntityItemInHand(ent, blockitem.buildItem(0, 0, 0));
			entity.makeSoundToPlayer(ent, "RANDOM_BREAK");
		} else {
			addTimeoutTask(new Date().getTime(), {
				func: function (ent, item_, tag){
					const item = inventory.getEntityItemInHand(ent);
					if (!item.getId()) return;
					if (item.getNamedTag() === null || item.getNamedTag().getString('NWeaponNameTag') === null) return;
					if (item.getNamedTag().getString('NWeaponNameTag') != tag) return;
					inventory.setEntityItemInHand(ent, item_);
				},
				args: [ent, item_, item.getNamedTag().getString('NWeaponNameTag')]
			});
		}
	} else {
		// 护甲耐久处理
		let inv = inventory.getPlayerInv(ent);
		for (let i = 36; i < 40; i++) {
			let item = inventory.getInventorySlot(inv, i);
			if (!item.getId()) continue;
			if (item.getNamedTag() === null || item.getNamedTag().getString('NWeaponNameTag') === null) continue;
			const data = getNWeaponConfig(item.getNamedTag().getString('NWeaponNameTag'));
			if (!data) continue;
			const item_ = setItemUnbreaking(item, data.耐久);
			if (!item_) continue;
			if (item_.getNamedTag().getInt('Unbreaking') < 1) {
				inventory.editInvBySlot(inv, i, blockitem.buildItem(0, 0, 0));
				entity.makeSoundToPlayer(ent, "RANDOM_BREAK");
			} else {
				inventory.editInvBySlot(inv, i, item_);
			}
		}
		addTimeoutTask(new Date().getTime(), {
			func: function (ent, item_){
				inventory.setPlayerInv(ent, inv);
			},
			args: [ent, inv]
		});
	}
}
/*
 * @brief :扣除物品的耐久
 *
 * @param Item item:物品对象
 * @param int maxUnbreak:最大耐久
 * @return item
 */
function setItemUnbreaking(item, maxUnbreak) {
	let oldLore = blockitem.getItemLore(item);
	const itemDamage = item.getDamage();// 物品的耐久
	if (item.getNamedTag().getInt('Unbreaking')) {
		const num = item.getNamedTag().getInt('Unbreaking') -1;
		const maxDurability = item.getMaxDurability();
		oldLore = oldLore.replace(/§r§l§2耐久§2:§7 .+§n§j§r/, "§r§l§2耐久§2:§7 "+num+"/"+maxUnbreak+"§n§j§r");
		item.setDamage(maxDurability - Math.floor(maxDurability * num / maxUnbreak));
		item.getNamedTag().putInt('Unbreaking', num);
	} else {
		return null;
	}
	item.setNamedTag(item.getNamedTag());
	blockitem.setItemLore(item, oldLore);
	
	return item;
}
function EntityArmorChangeEvent(event) {// 实体护甲更改事件
	let player = event.getEntity();
	if (!isPlayer(player)) {
		return;
	}
	const Attr = GetPlayerAttr(player);
	const health = Attr.血量加成 * (1 + defineData(Attr.生命加成));
	if (RSHealthAPI) {// 若存在血量核心
		let PlayerHealth = RSHealthAPI.getPlayerHealth(player);
		PlayerHealth.setMaxHealth("nweapon", health);
		const H = PlayerHealth.getHealth();
		const MaxH = PlayerHealth.getMaxHealth();
		player.setHealth(H > MaxH ? MaxH : H);
	} else {
		if (health != 20 && player.getMaxHealth() != health) {
			player.setMaxHealth(health);
			if (player.getHealth() > health) {
				player.setHealth(health);
			}
		}
	}
}
var DeathTipsTimeout = {};
function PlayerDeathEvent(event) {// 玩家死亡事件
	let Player = event.getEntity();
	if (DeathTipsTimeout[Player.name] && DeathTipsTimeout[Player.name]+3000 > new Date().getTime()) {
		event.setDeathMessage("");
		return;
	} else {
		DeathTipsTimeout[Player.name] = new Date().getTime();
	}
	let data = PlayerDeathData[Player.name];
	if (data) {
		let tips = "{damager} 击败了 {player}";
		if (WeaponConfig[data[1]] && WeaponConfig[data[1]].击杀提示) {
			tips = WeaponConfig[data[1]].击杀提示;
		}
		event.setDeathMessage(tips.replace("{damager}", data[0]).replace("{name}", data[1]).replace("{player}", Player.name));
		delete PlayerDeathData[Player.name];
	}
}
// 虚拟物品栏操作事件
function FakeSlotChangeEvent(event) {
	var player = event.getPlayer();
	var slot = event.getAction().getSlot();
	var inv = event.getAction().getInventory();
	var newItem = event.getAction().getTargetItem();
	switch (event.getAction().getInventory().getName()) {
		case "锻造": {
			ForgingFakeInvChange.call(this, event, player, slot, inv, newItem);
			break;
		}
		case "精工": {
			SeikoFakeInvChange.call(this, event, player, slot);
			break;
		}
		case "强化": {
			StrengthFakeInvChange.call(this, event, player, slot);
			break;
		}
		case "觉醒": {
			UpgradeFakeInvChange.call(this, event, player, slot);
			break;
		}
	}
}
// 虚拟物品栏关闭事件
function InventoryCloseEvent(event) {
	var player = event.getPlayer();
	var inv = event.getInventory();
	switch (inv.getName()) {
		case "锻造": {
			ForgingFakeInvClose.call(this, event, player, inv);
			break;
		}
		case "精工": {
			SeikoFakeInvClose.call(this, event, player, inv);
			break;
		}
		case "强化": {
			StrengthFakeInvClose.call(this, event, player, inv);
			break;
		}
		case "觉醒": {
			UpgradeFakeInvClose.call(this, event, player, inv);
			break;
		}
	}
}
// 升级 - 虚拟物品栏物品更改事件处理
var UpgradeFakeInvChange = function (event, player, slot){
	if (slot != 0) {
		return event.setCancelled(true);
	}
}
// 升级 - 虚拟物品栏关闭事件处理
var UpgradeFakeInvClose = function (event, player, inv){
	let itemlist = inventory.getItemsInInv(inv);
	let item = inventory.getInventorySlot(inv, 0);
	if (item.getId() === 0) {
		return;
	}
	let backItem = function (msg){
		if (msg) {
			player.sendMessage("[NWeapon] "+msg);
		}
		blockitem.addItemToPlayer(player, item);
		/*if (UpgradePlayerTempData[player.name][2]) {
			for (n = 3; n < 5; n++) {
				var slotItem = inventory.getInventorySlot(inv, 0);
				if (slotItem.getId() != 0) {
					blockitem.addItemToPlayer(player, slotItem);
				}
			}
		}*/
	}
	if(!UpgradePlayerTempData[player.name]) {
		return backItem();
	}
	if(item.getNamedTag().getString('NWeaponNameTag') != UpgradePlayerTempData[player.name][0].join(";")) {
		return backItem("§c请在第一格放入 " + UpgradePlayerTempData[player.name][0][1]);
	}
	if(UpgradePlayerTempData[player.name][2][3] && !examineNeed(UpgradePlayerTempData[player.name][2][3].split("||"), player)) {
		return backItem();
	}
	const itemconfig = getNTagConfig(UpgradePlayerTempData[player.name][1].join(";"));
	let newitem = getItem(UpgradePlayerTempData[player.name][1][1], itemconfig);
	let oldLore = blockitem.getItemLore(newitem);
	let nbtObj, nbtObj_ = item.getNamedTag().getString('GemList');
	if (nbtObj_ != '') {
		nbtObj = JSON.parse(nbtObj_);// {info: HandItemData.镶嵌, inlay: []};
		if (itemconfig.镶嵌.join(";;").indexOf(nbtObj.info.join(";;")) === -1) {
			return backItem("§c宝石槽无法兼容");
		}
		nbtObj.info = itemconfig.镶嵌;
		nbtObj.inlay.length = nbtObj.info.length;
		newitem.getNamedTag().putString('GemList', JSON.stringify(nbtObj));
		for (var i = 0; i<nbtObj.inlay.length; i++) {
			if(nbtObj.inlay[i]) {
				oldLore = oldLore.replace("§r§3[§7可镶嵌<" + nbtObj.info[i] + ">§3]", nbtObj.inlay[i]);
			}
		}
	}
	nbtObj = item.getNamedTag().getString('Seiko');
	let loreArr = [];
	if (nbtObj != '') {
		newitem.getNamedTag().putString('Seiko', nbtObj);
		nbtObj = JSON.parse(nbtObj);
		loreArr.push("§r§6§l精工等级:§e "+getGradeSymbol.seiko(nbtObj.level)+" §r");
	}
	nbtObj = item.getNamedTag().getString('Strengthen');
	if (nbtObj != '') {
		newitem.getNamedTag().putString('Strengthen', nbtObj);
		nbtObj = JSON.parse(nbtObj);
		loreArr.push("§r§7§l======【 §c强化§7 】======;§r§fLv§e. "+getGradeSymbol.strengthen(nbtObj.level)+" §r");
	}
	newitem.setNamedTag(newitem.getNamedTag());
	blockitem.setItemLore(newitem, oldLore+loreArr.join(";"));
	player.sendMessage("[NWeapon] §aSuccess!");
	
	blockitem.addItemToPlayer(player, newitem);
}
// 强化 - 虚拟物品栏物品更改事件处理
var StrengthFakeInvChange = function (event, player, slot){
	if (slot != 0) {
		return event.setCancelled(true);
	}
}
// 强化 - 虚拟物品栏关闭事件处理
var StrengthFakeInvClose = function (event, player, inv){
	let itemlist = inventory.getItemsInInv(inv);
	let HandItem = inventory.getInventorySlot(inv, 0);
	if (HandItem.getId() === 0) {
		return;
	}
	let backItem = function (msg){
		if (msg) {
			player.sendMessage("[NWeapon] "+msg);
		}
		blockitem.addItemToPlayer(player, HandItem);
	}
	if (!HandItem.getCustomName() || !HandItem.getNamedTag().getString('NWeaponNameTag')) {
		return backItem("§c非NWeapon物品");
	}
	var nTag = HandItem.getNamedTag().getString('NWeaponNameTag').split(";");
	var index = ["Weapon", "Armor"].indexOf(nTag[0]);
	let HandItemData, HandItemName = HandItem.getCustomName() || HandItem.getName();
	if (index === -1) {
		return backItem("§c请在第一格放入NWeapon装备");
	} else if (index === 0) {
		HandItemData = WeaponConfig[nTag[1]];
	} else if (index === 1) {
		HandItemData = ArmorConfig[nTag[1]];
	}
	if (!HandItemData) {
		return backItem(HandItemName+" §r§c的配置文件丢失");
	}
	if (HandItemData.不可强化) {
		return backItem("§c装备 "+HandItemName+" §r§c不可强化");
	}
	let nbtObj = HandItem.getNamedTag().getString('Strengthen');
	if (nbtObj === '') {
		nbtObj = {level: 0};
		HandItem.setNamedTag(HandItem.getNamedTag().putString('Strengthen', JSON.stringify(nbtObj)));
	} else {
		nbtObj = JSON.parse(nbtObj);
	}
	if (!examineNeed(Config.Strengthen.need[nbtObj.level].split("||"), player)) {
		return backItem();
	}
	let oldLore = blockitem.getItemLore(HandItem),
		probability = Config.Strengthen.chance[nbtObj.level] + defineData(strengthFailedNum[player.name])*Config.Strengthen.failedAddition,
		failProtect = 0,
		straightUp = 0,
		luck = false;
	let bagitems = inventory.getPlayerInv(player);
	for (var i = 0; i < 9; i++) {
		let item = inventory.getInventorySlot(bagitems, i);
		if (item.getCustomName() && item.getNamedTag().getString('NWeaponNameTag')) {
			let arr = item.getNamedTag().getString('NWeaponNameTag').split(";");
			if (arr[0] === ItemTypeList["强化石"]) {
				let count = 1;
				luck_ = item.getNamedTag().getString('Luck') || 0;
				failProtect_ = item.getNamedTag().getString('FailProtect') || 0;
				straightUp_ = item.getNamedTag().getString('StraightUp') || 0;
				if (straightUp && straightUp_) {
					continue;
				}
				if (straightUp_ > 0) {
					if (straightUp_ > nbtObj.level) {
						probability = 1;
						straightUp = straightUp_;
					} else {// 不符合消耗条件，跳过直升石
						continue;
					}
				}
				if (luck && luck_) {
					continue;
				}
				if (!isNaN(luck_) && luck_ > 0) {
					if (item.getNamedTag().getString('stacking')) {
						count = Math.ceil(1/luck_);
						if (item.getCount() < count) {
							count = item.getCount();
						}
					}
					probability += Number(luck_) * count;
					luck = true;
				}
				if (failProtect && failProtect_) {
					continue;
				}
				failProtect = !isNaN(failProtect_) ? Number(failProtect_) : 0;
				item.setCount(count);
				blockitem.removeItemToPlayer(player, item);
				player.sendMessage("[NWeapon] §7你消耗了 "+item.getCustomName()+ "§r§7 *"+count);
			}
		}
	}
	if (getProbabilisticResults(probability)) {
		if (straightUp) {
			nbtObj.level = straightUp;
		} else {
			nbtObj.level ++;
		}
		if (oldLore.indexOf("§r§7§l======【 §c强化§7 】======;§r§fLv§e.") > -1) {
			oldLore = oldLore.replace(/§r§7§l======【 §c强化§7 】======;§r§fLv§e\. .+ §r/, "§r§7§l======【 §c强化§7 】======;§r§fLv§e. "+getGradeSymbol.strengthen(nbtObj.level)+" §r");
		} else {
			oldLore += "§r§7§l======【 §c强化§7 】======;§r§fLv§e. "+getGradeSymbol.strengthen(nbtObj.level)+" §r";
		}
		if (Config.Strengthen.broadcastMessage && nbtObj.level >= Config.Strengthen.broadcastMessage[0]) {
			server.broadcastMessage(Config.Strengthen.broadcastMessage[1].replace("%p", player.name).replace("%lv", nbtObj.level).replace("%weapon", HandItemName));
		} else {
			logger.info(player.name+"淬炼 "+HandItemName+" §r至 "+nbtObj.level+" 级");
		}
		strengthFailedNum[player.name] = 0;
		player.sendTitle("§a§l+ 淬炼成功 +", "§e"+nbtObj.level+"级 §6"+getGradeSymbol.strengthen(nbtObj.level));
		blockitem.setItemLore(HandItem, oldLore);
		HandItem.setNamedTag(HandItem.getNamedTag().putString('Strengthen', JSON.stringify(nbtObj)));
		blockitem.addItemToPlayer(player, HandItem);
	} else {
		let num = 0;
		for(i = 0; i<Config.Strengthen.failed.length; i++) {
			if (nbtObj.level <= Config.Strengthen.failed[i][0]) {
				num = getArrayProbabilisticResults(Config.Strengthen.failed[i], 1);
				break;
			}
		}
		if (getProbabilisticResults(failProtect) || num === -1) {
			player.sendTitle("§c§l- 淬炼失败 -", "§6本次受到保护");
			blockitem.addItemToPlayer(player, HandItem);
		} else {
			if (num === 0) {
				player.sendTitle("§c§l- 淬炼失败 -", "§l§4武器在淬炼中损坏");[]
			} else {
				let res = nbtObj.level - num;
				if (res < 1) {
					res = 1;
				}
				player.sendTitle("§c§l- 淬炼失败 -", "§4下降"+(nbtObj.level - res)+"级 §6"+getGradeSymbol.strengthen(res));
				seikoFailedNum[player.name] ++;
				nbtObj.level = res;
				oldLore = oldLore.replace(/§r§7§l======【 §c强化§7 】======;§r§fLv§e\. .+ §r/, "§r§7§l======【 §c强化§7 】======;§r§fLv§e. "+getGradeSymbol.strengthen(res)+" §r");
				blockitem.setItemLore(HandItem, oldLore);
				HandItem.setNamedTag(HandItem.getNamedTag().putString('Strengthen', JSON.stringify(nbtObj)));
				blockitem.addItemToPlayer(player, HandItem);
			}
		}
	}
}
// 精工 - 虚拟物品栏物品更改事件处理
var SeikoFakeInvChange = function (event, player, slot){
	if (slot != 0) {
		return event.setCancelled(true);
	}
}
// 精工 - 虚拟物品栏关闭事件处理
var SeikoFakeInvClose = function (event, player, inv){
	let item = inventory.getInventorySlot(inv, 0);
	if (item.getId() === 0) {
		return;
	}
	let backItem = function (msg){
		if (msg) {
			player.sendMessage("[NWeapon] "+msg);
		}
		blockitem.addItemToPlayer(player, item);
	}
	if (!item.getCustomName() || !item.getNamedTag().getString('NWeaponNameTag')) {
		return backItem("§c非NWeapon物品");
	}
	var nTag = item.getNamedTag().getString('NWeaponNameTag').split(";");
	var index = ["Weapon", "Armor"].indexOf(nTag[0]);
	let HandItemData, HandItemName = item.getCustomName() || item.getName();
	if (index === -1) {
		return backItem("§c请在第一格放入NWeapon装备");
	} else if (index === 0) {
		HandItemData = WeaponConfig[nTag[1]];
	} else if (index === 1) {
		HandItemData = ArmorConfig[nTag[1]];
	}
	if (!HandItemData) {
		return backItem(HandItemName+" §r§c的配置文件丢失");
	}
	if (HandItemData.不可精工) {
		return backItem("§c装备 "+HandItemName+" §r§c不可精工");
	}
	let nbtObj = item.getNamedTag().getString('Seiko');
	if (nbtObj === '') {
		nbtObj = {level: 0};
		item.setNamedTag(item.getNamedTag().putString('Seiko', JSON.stringify(nbtObj)));
	} else {
		nbtObj = JSON.parse(nbtObj);
	}
	if (manager.getMoney(player) < Config.Seiko.needMoney[nbtObj.level]) {
		return backItem("§c金币不足，您至少需要 "+Config.Seiko.needMoney[nbtObj.level]+" 金钱");
	}
	manager.reduceMoney(player, Config.Seiko.needMoney[nbtObj.level]);
	let oldLore = blockitem.getItemLore(item), probability = Config.Seiko.chance[nbtObj.level] + defineData(seikoFailedNum[player.name])*Config.Seiko.failedAddition;
	let failProtect = straightUp = 0, luck = false;
	let bagitems = inventory.getPlayerInv(player);
	for (var i = 0; i < 9; i++) {
		let seiko_item = inventory.getInventorySlot(bagitems, i);
		if (seiko_item.getCustomName() && seiko_item.getNamedTag().getString('NWeaponNameTag')) {
			let arr = seiko_item.getNamedTag().getString('NWeaponNameTag').split(";");
			if (arr[0] === ItemTypeList["精工石"]) {
				let count = 1;
				luck_ = seiko_item.getNamedTag().getString('Luck') || 0;
				failProtect_ = seiko_item.getNamedTag().getString('FailProtect') || 0;
				straightUp_ = seiko_item.getNamedTag().getString('StraightUp') || 0;
				if (straightUp && straightUp_) {
					continue;
				}
				if (straightUp_ > 0) {
					if (straightUp_ > nbtObj.level) {
						probability = 1;
						straightUp = straightUp_;
					} else {// 不符合消耗条件，跳过直升石
						continue;
					}
				}
				if (luck && luck_) {
					continue;
				}
				if (!isNaN(luck_) && luck_ > 0) {
					if (seiko_item.getNamedTag().getString('stacking')) {
						count = Math.ceil(1/luck_);
						if (seiko_item.getCount() < count) {
							count = seiko_item.getCount();
						}
					}
					probability += Number(luck_) * count;
					luck = true;
				}
				if (failProtect && failProtect_) {
					continue;
				}
				failProtect = !isNaN(failProtect_) ? Number(failProtect_) : 0;
				seiko_item.setCount(count);
				blockitem.removeItemToPlayer(player, seiko_item);
				player.sendMessage("[NWeapon] §7你消耗了 "+seiko_item.getCustomName()+ "§r§7 *"+count);
			}
		}
	}

	if (getProbabilisticResults(probability)) {
		if (straightUp) {
			nbtObj.level = straightUp;
		} else {
			nbtObj.level ++;
		}
		if (oldLore.indexOf("§r§6§l精工等级:§e ") > -1) {
			oldLore = oldLore.replace(/§r§6§l精工等级:§e .+ §r/, "§r§6§l精工等级:§e "+getGradeSymbol.seiko(nbtObj.level)+" §r");
		} else {
			oldLore += "§r§6§l精工等级:§e "+getGradeSymbol.seiko(nbtObj.level)+" §r";
		}
		if (Config.Seiko.broadcastMessage && nbtObj.level >= Config.Seiko.broadcastMessage[0]) {
			server.broadcastMessage(Config.Seiko.broadcastMessage[1].replace("%p", player.name).replace("%lv", nbtObj.level).replace("%weapon", HandItemName));
		} else {
			logger.info(player.name+"精工 "+HandItemName+" §r至 "+nbtObj.level+" 级");
		}
		seikoFailedNum[player.name] = 0;
		player.sendTitle("§a§l+ 精工成功 +", "§e"+nbtObj.level+"级 §6"+getGradeSymbol.seiko(nbtObj.level));
		blockitem.setItemLore(item, oldLore);
		item.setNamedTag(item.getNamedTag().putString('Seiko', JSON.stringify(nbtObj)));
		blockitem.addItemToPlayer(player, item);
	} else {
		let num = 0;
		for(i = 0; i<Config.Seiko.failed.length; i++) {
			if (nbtObj.level <= Config.Seiko.failed[i][0]) {
				num = getArrayProbabilisticResults(Config.Seiko.failed[i], 1);
				break;
			}
		}
		if (getProbabilisticResults(failProtect) || num === -1) {
			backItem("§c§l- 精工失败 -", "§6本次受到保护");
			blockitem.addItemToPlayer(player, item);
		} else {
			let res = nbtObj.level - (num + 1);
			if (res < 1) {
				res = 1;
			}
			player.sendTitle("§c§l- 精工失败 -", "§4下降"+(nbtObj.level - res)+"级 §6"+getGradeSymbol.seiko(res));
			seikoFailedNum[player.name] ++;
			nbtObj.level = res;
			oldLore = oldLore.replace(/§r§6§l精工等级:§e .+ §r/, "§r§6§l精工等级:§e "+getGradeSymbol.seiko(res)+" §r");
			blockitem.setItemLore(item, oldLore);
			item.setNamedTag(item.getNamedTag().putString('Seiko', JSON.stringify(nbtObj)));
			blockitem.addItemToPlayer(player, item);
		}
	}
}
// 锻造 - 虚拟物品栏物品更改事件处理
var ForgingFakeInvChange = function (event, player, slot, inv, newItem){
	if (!PlayerSmithingTempData[player.name]) {
		PlayerSmithingTempData[player.name] = null;
	}
	if (slot == 0) {
		let paperData = PaperConfig[newItem.getCustomName()];
		if (paperData) {
			if (!PlayerData[player.getName()]) PlayerData[player.getName()] = { exp: 0, level: 0 };
			if (paperData.限制等级 > PlayerData[player.getName()].level) {
				player.sendMessage("[NWeapon] §c您的锻造师等级不足");
			} else {
				if (paperData.外形[0] == newItem.getId() && paperData.外形[1] == newItem.getDamage()) {
					PlayerSmithingTempData[player.name] = JSON.parse(JSON.stringify(paperData));//消除对象关联性，这非常重要！！！
					if (PlayerSmithingTempData[player.name]) return;
					player.sendMessage("[NWeapon] §c配置文件中没有这个锻造方案");
				} else {
					player.sendMessage("[NWeapon] §c这不是有效的锻造图纸");
				}
			}
		} else {
			player.sendMessage("[NWeapon] §c锻造图纸不存在");
		}
		event.setCancelled(true);
	} else {
		if (!PlayerSmithingTempData[player.name]) {
			player.sendMessage("[NWeapon] §c请先在第一格放入图纸");
			event.setCancelled(true);
			return;
		}
		if (Config.锻造模式 == 0) {
			if (slot == 1) {
				let TempData = PlayerSmithingTempData[player.name].方案[1];
				let data = WeaponConfig[data[0]] || ArmorConfig[data[0]];
				if (data === undefined) {
					player.sendMessage("[NWeapon] §c这不是一个NWeapon装备");
					event.setCancelled(true);
					return;
				}
				if (newItem.getCustomName() === TempData[0] && newItem.getId() === TempData[1] && newItem.getDamage() === TempData[2]) {
					if (TempData[3]) {
						if (blockitem.getNBTString(newItem) != blockitem.getNBTString(getItem(TempData[0], data))) {
							player.sendMessage("[NWeapon] §c你不能为这个NWeapon装备进行锻造");
							event.setCancelled(true);
							return;
						}
					}
				} else {
					player.sendMessage("[NWeapon] §c这不是图纸需求的装备");
					event.setCancelled(true);
					return;
				}
			} else {
				if (inventory.getInventorySlot(inv, 1).getId() == 0) {
					player.sendMessage("[NWeapon] §c请先在第2格放入装备");
					event.setCancelled(true);
					return;
				}
				if (inventory.getInventorySlot(inv, slot - 1).getId() == 0) {
					player.sendMessage("[NWeapon] §c请先在第" + (slot - 1) + "格放入材料");
					event.setCancelled(true);
					return;
				}
			}
		} else if (Config.锻造模式 === 1) {
			if (inventory.getInventorySlot(inv, slot - 1).getId() == 0) {
				player.sendMessage("[NWeapon] §c请先在第" + (slot - 1) + "格放入材料");
				event.setCancelled(true);
				return;
			}
		}
	}
}
// 锻造 - 虚拟物品栏关闭事件处理
var ForgingFakeInvClose = function (event, player, inv){
	let itemlist = inventory.getItemsInInv(inv);
	let drawing = inventory.getInventorySlot(inv, 0);
	if (drawing.getId() === 0) {
		return player.sendMessage("[NWeapon] §7已取消锻造，未放入图纸");
	}
	let weapon, backList = [], startI;
	let formula = PlayerSmithingTempData[player.name].方案[0];
	let paperExp = PlayerSmithingTempData[player.name].获得经验;
	if (Config.锻造模式 === 0) {
		weapon = inventory.getInventorySlot(inv, 1);
		if (weapon.getId() === 0) {
			blockitem.addItemToPlayer(player, itemlist[0]);
			return player.sendMessage("[NWeapon] §7已取消锻造，未放入装备");
		}
		backList = [itemlist[0], itemlist[1]];
		startI = 2;
	} else {
		let name = PlayerSmithingTempData[player.name].方案[1][0];
		let data = WeaponConfig[name] || ArmorConfig[name];
		if (!data) {
			for (var i = 0, len = itemlist.length; i < len; i++) {
				blockitem.addItemToPlayer(player, itemlist[i]);
			}
			return player.sendMessage("[NWeapon] §7已取消锻造，该锻造图装备没有相应的配置文件");
		}
		weapon = getItem(name, data);
		backList = [itemlist[0]];
		startI = 1;
	}
	delete PlayerSmithingTempData[player.name];
	let Strength = Number(((Math.random().toString().substr(2, 2) - 0 + 1) / 1.7).toFixed(2));
	// 放入的物品列表
	for (var ix = startI, lenx = itemlist.length; ix < lenx; ix++) {
		let item = itemlist[ix], name = item.getCustomName() || item.getName();
		if (formula[name]) {
			let itemCount = item.getCount();
			let res = formula[name][2] - itemCount;
			if (res < 1) {// 需求扣完了
				if (res * -1 > 0) {
					item.setCount(res * -1);// 返回多余的材料
					blockitem.addItemToPlayer(player, item);
				}
				item.setCount(itemCount + res);// 返回被扣材料
				backList.push(item);
				delete formula[name];
			} else {// 需求没扣完
				formula[name][2] = res;
				backList.push(item);// 返回被扣材料
			}
			continue;
		}
		// 锻造石处理
		let NameTag;
		if (item.getNamedTag() == null) {
			NameTag = false;
		} else {
			NameTag = item.getNamedTag().getString('NWeaponNameTag');
			if (NameTag && NameTag.slice(0, NameTag.indexOf(";")) === ItemTypeList["锻造石"] && Strength < 100) {
				backList.push(item);
				count:
				for (let i = 0, len = item.getCount(); i<len; i++) {
					Strength += item.getNamedTag().getString('Strength')*100;
					if (Strength >= 100) {
						Strength = 100;
						let surplus = len-i-1;
						item.setCount(surplus);
						blockitem.addItemToPlayer(player, item);
						if (surplus === 0) {
							backList[backList.length] = backList.length - 2;

						}
						break;
					} else {
						item.setCount(i);
						backList[backList.length - 1] = item;
					}
				}
				continue;
			}
		}
		// 未知材料返还
		blockitem.addItemToPlayer(player, item);
	}
	if (JSON.stringify(formula) != "{}") {
		let str  = [];
		for (var i in formula) {
			str.push(i+" *"+formula[i][2]);
		}
		player.sendMessage("[NWeapon] §7已取消锻造");
		player.sendMessage(Config.NeedFailedTips.replace("%1", str.join("、")));
		for (var i = 0; i < backList.length; i++) {
			blockitem.addItemToPlayer(player, backList[i]);
		}
		return;
	}
	
	if (PaperConfig[drawing.getCustomName()].消耗 === false) {
		blockitem.addItemToPlayer(player, drawing);
	} else {// 处理多余图纸的返回
		let num = drawing.getCount() - 1;
		if (num > 0) {
			drawing.setCount(drawing.getCount() - 1);
			blockitem.addItemToPlayer(player, drawing);
		}
	}
	let index = getArrayProbabilisticResults(Config.锻造[1]), addxp = Config.锻造[1].length - index;
	if (paperExp) {
		addxp = paperExp*5+(getRandomNum([1, 2]) === 1 ? getRandomNum([1, 2]) : -getRandomNum([1, 2]));
	}
	if (Config.ForingExp.onlySameLevel) {
		if (PaperConfig[drawing.getCustomName()].限制等级 < PlayerData[player.getName()].level) {
			player.sendMessage("[NWeapon] §7您正在锻造低等级图纸");
			addxp = Config.ForingExp.nonSameLevelGive;
		}
	}
    addxp = Number(addxp.toFixed(2));// 防止浮点数错误
	PlayerData[player.getName()].exp = Math.round((PlayerData[player.getName()].exp + addxp)*10000)/10000;
	PlayerData[player.getName()].exp = Number(PlayerData[player.getName()].exp.toFixed(2));// 防止浮点数错误
	PlayerData[player.getName()].level = Math.floor(eval(Config.锻造等级.等级公式.replace(/{经验}/g, PlayerData[player.getName()].exp)));
	if (isNaN(PlayerData[player.getName()].level)) PlayerData[player.getName()].level = 0;
	PlayerData[player.getName()].req = eval(Config.锻造等级.经验公式.replace(/{等级}/g, PlayerData[player.getName()].level + 1)) - PlayerData[player.getName()].exp;
	PlayerData[player.getName()].req = Number(PlayerData[player.getName()].req.toFixed(2));// 防止浮点数错误
	manager.writeFile("./plugins/BlocklyNukkit/NWeapon/PlayerData.json", JSON.stringify(PlayerData));
	player.sendMessage("[NWeapon] 恭喜您获得了 §l" + addxp + " §r点锻造经验");
	WeaponToForging(player, weapon, index, Strength);
}
// 普通装备升级为锻造装备
function WeaponToForging(player, item, index, Strength) {
	let data = WeaponConfig[item.getCustomName()] || ArmorConfig[item.getCustomName()];
	let AttrLore = [];
	let ForgingAttrNbt = { attr: {}, info: {} };
	let getForgingAttr = function(value, i) {
		/*if (Config.AttrDisplayPercent.indexOf(i) > -1) {
			return value;
		}*/
		let arr = [Config.锻造[2][index]];
		if (typeof(arr[0]) === "string") {
			arr = arr[0].split("-");
		}
		return Math.round((value * 1000) * getRandomNum(arr)) / 1000;
	}
	for (var i in data.锻造属性) {
		if (typeof (data.锻造属性[i]) === 'string') {
			let arr = data.锻造属性[i].split("-");
			ForgingAttrNbt.attr[i] = [getForgingAttr(arr[0], i), getForgingAttr(arr[1], i)];
		} else {
			ForgingAttrNbt.attr[i] = [getForgingAttr(data.锻造属性[i], i)];
		}
		AttrLore.push("§r§a" + i + ":§d " + valueToString(ForgingAttrNbt.attr[i], i));
	}
	let 强度 = "||||||||||||||||||||".split("");
	强度.splice(Math.ceil(Strength / 5), 0, "§7");
	let oldLore = blockitem.getItemLore(item);
	let oldType = oldLore.substr(0, 14);
	if (oldType === "§r§f[§b武器§f]§r") {
		oldLore = oldLore.replace("§r§f[§b武器§f]§r", "§r§f[§b锻造武器§f]§r");
	} else if (oldType === "§r§f[§e护甲§f]§r") {
		oldLore = oldLore.replace("§r§f[§e护甲§f]§r", "§r§f[§e锻造护甲§f]§r");
	}
	let lore = [
		"§r§4§l一一一一一一一一一一",
		"§r§2锻造属性:",
		AttrLore.join(";"),
		"§r§4§l一一一一一一一一一一",
		"§r§a品质: " + Config.锻造[0][index],
		"§r§a强度: §b[§a" + 强度.join("") + "§b]",
		"§r§7锻造者§6[§a§l" + player.name + "§r§6]"
	];
	blockitem.setItemLore(item, oldLore + lore.join(";"));
	ForgingAttrNbt.info.player = player.name;
	ForgingAttrNbt.info.intensity = Strength / 100;
	ForgingAttrNbt.info.playerlv = PlayerData[player.name].level;
	item.setNamedTag(item.getNamedTag().putString('forging', JSON.stringify(ForgingAttrNbt)));
	item = itemBindPlayer(item, player, false, true);
	blockitem.addItemToPlayer(player, item);
	player.sendMessage("[NWeapon] 锻造成功");
}

// - 功能性函数
function isPlayer(entity) {
	return entity instanceof Java.type("cn.nukkit.Player");
}
function getRandomNum(array){
	// 返回 [最小值, 最大值] 的随机值
	let length = 0;
	if (array.length === 1 && array[0] === array[1]) {
		return array[0];
	}
	array.forEach(function (v){
		let last = (v + []).split(".")[1];
		if (last && length < last.length) {
			length = last.length;
		}
	});
	length = Math.pow(10, length + 2);
	let minNum = array[0] * length;
	let maxNum = array[1] * length;
	return parseInt(Math.random() * (maxNum - minNum + 1) + minNum,10) / length;
}
function defineData(d) {
	return d ? new Number(d) : 0;
}
function getNTagConfig(ntag) {
	var arr = ntag.split(";");
	var config = eval(arr[0]+"Config");
	if (config && config[arr[1]]) {
		return config[arr[1]];
	}
	return false;
}
// 将数据可视化，输入data,属性输出min-max或x%
export function valueToString(data, i){
	let back = "";
	if (typeof(data) === "object") {
		if (data[0] == data[1]) {
			data = Number(data[0].toFixed(2));
		} else if (data.length === 1) {
			data = data[0];
		} else {
			return data[0]+" - "+data[1];
		}
	}
	if (Config.AttrDisplayPercent.indexOf(i) > -1) {
		data = (data*100).toFixed(2) + [];
		if (data.substring(data.length-3) === ".00") {
			data = (data - 0).toFixed(0);
		}
		back = data+"%%";
	} else {
		back = data;
	}
	if (data == 0) {
		back = 0;
	}
	return new String(back);
}
// 生命恢复 属性处理
function EntityRegainHealthEvent(event) {
	if (event.getRegainReason() != __EntityRegainHealthEvent.CAUSE_EATING) return;
	const addtion = GetPlayerAttr(event.getEntity(), 0, "生命恢复");
	//event.setAmount(event.getAmount() + addtion);
	//logger.info(event.getAmount())
	/*
	switch(event.getRegainReason()) {
		case __EntityRegainHealthEvent.CAUSE_CUSTOM: {
			logger.info("custom");
			break;
		}
		case __EntityRegainHealthEvent.CAUSE_EATING: {
			logger.info("eating");
			break;
		}
		case __EntityRegainHealthEvent.CAUSE_MAGIC: {
			logger.info("magic");
			break;
		}
		case __EntityRegainHealthEvent.CAUSE_REGEN: {
			logger.info("regen");
			break;
		}
		default :{
			logger.info("unknow");
		}
	}*/
	event.getEntity().heal(addtion)
}
// 登入和登出时处理..
function PlayerJoinEvent(event){
	let name = event.getPlayer().getName();
	seikoFailedNum[name] = 0;
	SetPlayerAttr(name, "装备武器", {});
	if (Config.defaultAttr) {
		SetPlayerAttr(name, "默认属性", Config.defaultAttr);
	}
	let tempAttr = manager.readFile("./plugins/BlocklyNukkit/NWeapon/PlayerAttrData/"+name+".json");
	if (tempAttr && tempAttr != "FILE NOT FOUND") {
		tempAttr = JSON.parse(tempAttr);
		data = database.memoryStorage.getItem("PlayerAttr");
		data[name].Effect = tempAttr.Effect;
		database.memoryStorage.setItem("PlayerAttr", data);
	}
}
function PlayerQuitEvent(event){
	let name = event.getPlayer().name,
		data = database.memoryStorage.getItem("PlayerAttr"),
		playerAttrData = JSON.stringify(data[name]);
	delete data[name];
	delete seikoFailedNum[name];
	delete strengthFailedNum[name];
	database.memoryStorage.setItem("PlayerAttr", data);
	manager.writeFile("./plugins/BlocklyNukkit/NWeapon/PlayerAttrData/"+name+".json", playerAttrData);
}
// 为玩家属性申请共享内存
if (!database.memoryStorage.getItem("PlayerAttr")) database.memoryStorage.setItem("PlayerAttr", {});
// 为怪物属性申请共享内存
if (!database.memoryStorage.getItem("MonsterAttr")) database.memoryStorage.setItem("MonsterAttr", {});
// 获取玩家属性，player为玩家对象、mode为数据模式 [Main随机后的值, 原始数据]
export function GetPlayerAttr(player, mode, key) {
	if (isPlayer(player)) {
		if (Config["worlds-disabled"].indexOf(player.getLevel().getName()) > -1) {
			return {};
		}
		player = player.getName();
	} else if (typeof(player) != "string") {
		return {};
	}
	let data = database.memoryStorage.getItem("PlayerAttr")[player];
	if (!data) {
		return {};
	}
	data = JSON.parse(JSON.stringify(data));
	if (mode) {
		for (var i in data.Effect) {
			if (!data.Main[i]) {
				data.Main[i] = [Number(data.Effect[i].level)];
				continue;
			}
			if(data.Main[i].length == 2) {
				data.Main[i][0] += Number(data.Effect[i].level);
				data.Main[i][1] += Number(data.Effect[i].level);
			} else if(data.Main[i].length == 1) {
				data.Main[i][0] += Number(data.Effect[i].level);
			}
		}
		return data;
	}
	if (key) {
		let back = data.Effect[key] ? data.Effect[key].level : 0;
		if (!data.Main[key] && back === 0) {
			return 0;
		}
		if (typeof(data.Main[key]) === "object") {
			back += getRandomNum(data.Main[key]);
			return back;
		}
		return data.Main[key] + back;
	}
	for (var i in data.Main) {
		if (data.Main[i][0] === data.Main[i][1]) {
			data.Main[i] = data.Main[i][0];
		} else {
			data.Main[i] = getRandomNum(data.Main[i]);
		}
	}
	for (var i in data.Effect) {
		if (data.Main[i]) {
			data.Main[i] += Number(data.Effect[i].level);
		} else {
			data.Main[i] = Number(data.Effect[i].level);
		}
	}
	return data.Main;
}
export function SetPlayerAttr(player, item, newAttr) {
	if (isPlayer(player)) {
		player = player.getName();
	} else if(typeof(item) != "string") {
		return false;
	}
	if (typeof(newAttr) === "string") newAttr = JSON.parse(newAttr);
	let data = database.memoryStorage.getItem("PlayerAttr");
	if (!data[player]) {
		data[player] = {Effect: {}, EffectSuit: [], Main: {}};
	}
	switch (item) {
		case "Effect": {//newAttr: {id: 1, level: 1, time: s};
			if (newAttr.id === false) {
				data[player].Effect = {};
				database.memoryStorage.setItem("PlayerAttr", data);
				return true;
			}
			let effectdata = data[player].Effect[newAttr.id];
			if (!effectdata) {
				effectdata = {level: 0, time: 0};
			}
			if (newAttr.level && newAttr.level > effectdata.level) {
				effectdata.level = newAttr.level;
			}
			if (newAttr.time) {
				effectdata.time = Number((new Date().getTime()/1000).toFixed(0)) + Number(newAttr.time);
				data[player].Effect[newAttr.id] = effectdata;
				//entity.addEntityEffect(server.getPlayer(player), newAttr.id, effectdata.level, effectdata.time);
			} else {
				delete data[player].Effect[newAttr.id];
			}
			database.memoryStorage.setItem("PlayerAttr", data);
			return true;
		}
		case "EffectSuit": {//newAttr: ["suit1", "suit2"]
			data[player]["EffectSuit"] = newAttr;
			database.memoryStorage.setItem("PlayerAttr", data);
			return data[player]["EffectSuit"];
		}
		case "Main": {
			logger.warning("setPlayerAttr(): '"+item+"' is the wrong item parameter.");
			return false;
		}
	}
	if (newAttr['delete']) {
		delete data[player][item];
		return true;
	}
	if (!data[player][item]) data[player][item] = {};
	let oldAttr = data[player][item];
	for (var i in newAttr) {
		if (typeof(newAttr[i]) === 'string' || typeof(newAttr[i]) === 'number') {
			newAttr[i] = [Number(newAttr[i]), Number(newAttr[i])];
		}
		if (typeof(newAttr[i]) === 'object') {
			if (!data[player].Main[i]) data[player].Main[i] = [0, 0];
			for(let k = 0; k<newAttr[i].length; k++) {
				data[player].Main[i][k] = data[player].Main[i][k] - (oldAttr[i] ? oldAttr[i][k] : 0) + newAttr[i][k];
			}
			continue;
		}
	}
	for (var i in oldAttr) {// 处理oldAttr有但是newAttr没有的属性
		if (!newAttr[i]) if (typeof(oldAttr[i]) === 'object') {
			if (!data[player].Main[i]) data[player].Main[i] = [0, 0];
			for(let k = 0; k<oldAttr[i].length; k++) {
				data[player].Main[i][k] = data[player].Main[i][k] - oldAttr[i][k];
			}
		} else {
			data[player].Main[i] = data[player].Main[i] - oldAttr[i];
		}
	}
	data[player][item] = newAttr;
	database.memoryStorage.setItem("PlayerAttr", data);
	if (JSON.stringify(newAttr).length === 2) {
		delete data[player][item];
	}
	return true;
}
export function isBanPutawayAtNWeapon(itemTag) {
	const data = getNWeaponConfig(itemTag);
	if (data) {
		return data.禁止上架 ? true : false;
	}
	return true;
}
export function getNWeaponConfig(itemTag) {
	const index_ = itemTag.indexOf(";");
	const arr = [itemTag.substr(0, index_), itemTag.substr(index_+1)];
	switch (arr[0]) {
		case "Weapon": {
			if (WeaponConfig[arr[1]]) {
				return WeaponConfig[arr[1]] || null;
			} else {
				return null;
			}
			break;
		}
		case "Armor": {
			if (ArmorConfig[arr[1]]) {
				return ArmorConfig[arr[1]] || null;
			} else {
				return null;
			}
			break;
		}
		case "Gem": {
			if (GemConfig[arr[1]]) {
				return GemConfig[arr[1]] || null;
			} else {
				return null;
			}
			break;
		}
		case "Jewelry": {
			if (JewelryConfig[arr[1]]) {
				return JewelryConfig[arr[1]] || null;
			} else {
				return null;
			}
			break;
		}
		default: {
			return null;
		}
	}
}
var getGradeSymbol = {
	seiko: function(level) {
		let str = "";
		let loop = function (lv){
			for(i = 0; i < Config.GradeSymbol.list[0].length; i++) {
				let v = Config.GradeSymbol.list[0][i];
				if (lv >= v) {
					str += Config.GradeSymbol.list[1][i];
					return loop(lv - v);
				}
			}
		}
		loop(level);
		return str;
	},
	strengthen: function (lv){
		return Config.Strengthen.style.firstList[lv]+Array(Number(lv)+1).join(Config.Strengthen.style.icon);
	}
}
// 获取概率结果，传入数值返回布尔值
function getProbabilisticResults(value){
	if (isNaN(value)) {
		return false;
	} else {
		value = Number(value).toFixed(5);
	}
	let length = 0;
	value = value + [];
	if (value <= 0) {
		return false;
	} else if (value < 1) {
		length = value.length - 2;
		value = value * Math.pow(10, length);
	} else if (value >= 1) {
		return true;
	}
	if ((Math.random() + []).substr(3, length) - 0 + 1 > value) return false;
	return true;
}
/**
 * 获取数组概率结果，传入总和为1的数组返回选中概率的下标(下标从0开始)
 * @param array {Array} 数组 
 * @param index {number} 下标（默认为0）
 * @returns {index} 被选中的下标
 * @example
 *   getArrayProbabilisticResults(['xx', 0.1, 0.2, 0.7], 1);
 */
function getArrayProbabilisticResults(array, index){
	if (index) {
		array = JSON.parse(JSON.stringify(array));
		array.splice(0, index);
	}
	if (array.length === 1) {
		return -1;
	}
	let length = 0, total = 0, random;
	array.forEach(function (v){
		total += Number(v);
		let num = (v + []).length - 2;
		if (length < num) length = num;
	});
	if (total < 0.9999 && total > 1.0001) {
		logger.warning("getArrayProbabilisticResults() has a error data: "+JSON.stringify(array));
        logger.info(total)
		return -1;
	}
	total = 0;
	random = (Math.random() + []).substr(3, length) - 0 + 1;
	for(i = 0; i<array.length; i++) {
		total += array[i] * Math.pow(10, length);
		if (total >= random) return i;
	}
}

/**
 * 检查并扣除需求，输入Array 输出Boolean
 * @param needArray {Array} 需求数组
 * @param player {player} 玩家对象
 * @returns {boolean} 是否成功
 * @example
 *   examineNeed(["nbt@任务材料孜然牛肉:1;§6孜然牛肉§f *1", "item@1:0:64", "money@10000"], player);
 */
function examineNeed(needArray, player) {
	let itemNeedList = [];
	let itemList = [];
	let NeedMoney = 0;
	for (var i = 0; i < needArray.length; i++) {
		let item = false;
		let type = needArray[i].split("@");
		let arr = type[1].split(";");
		let info = arr[1];
		let count = 1;
		arr = arr[0].split(":");// Item Data.
		if (type[0] === "item") {
			item = blockitem.buildItem(arr[0], arr[1], arr[2]);
			count = arr[2];
		} else if (type[0] === "nbt") {
			if (!NbtItem[arr[0]]) {
				logger.warning("nbt物品 "+arr[0]+" 不存在");
				return false;
			}
			let nbtdata = NbtItem[arr[0]].split(":");
			item = blockitem.buildItem(nbtdata[0], nbtdata[1], arr[1]);
			count = arr[1];
			if (nbtdata[2]) blockitem.putinNBTString(item, nbtdata[2]);
		} else if (type[0] === "money") {
			NeedMoney += new Number(arr[0]);
			continue;
		}
		if (!item) {
			logger.warning("配置文件中需求有误: "+needArray[i]);
			return false;
		}
		if (blockitem.hasItemToPlayer(player, item)) {
			itemList.push(item);
		} else {
			itemNeedList.push((info || item.getCustomName() || item.getName())+" *"+count);
			continue;
		}
	}
	if (itemNeedList.length > 0) {
		Config.NeedFailedTips && player.sendMessage(Config.NeedFailedTips.replace("%1", itemNeedList.join("、")));
		return false;
	}
	if (manager.getMoney(player) < NeedMoney) {
		Config.NeedFailedTips && player.sendMessage(Config.NeedFailedTips.replace("%1", "Money *"+(NeedMoney - manager.getMoney(player))));
		return false;
	}
	manager.reduceMoney(player, NeedMoney);
	itemList.forEach(function (v){
		blockitem.removeItemToPlayer(player, v);
	});
	return true;
}
// Config的数据格式化
if (Config["worlds-disabled"]) {
	Config["worlds-disabled"] = Config["worlds-disabled"].split(", ");
}

/**
 * 将物品转为 未打孔符文槽 的物品
 * @param item {item} 没有符文的物品
 * @returns {item}
 */
function toUnperformedRuneWeapon(item) {
    let loreArray = blockitem.getItemLore(item).split("§r§4§l一一一一一一一一一一;");
    loreArray[3] = '§r§u§n§e§[§e⇨§9§l❁§r§e⇦§r§u§n§e§];'+loreArray[3];
    let lore = loreArray.join("§r§4§l一一一一一一一一一一;");
    blockitem.setItemLore(item, lore);
    return item;
}
/**
 * 将 未打孔物品 转为 有孔符文槽 的物品
 * 或设置物品符文槽数
 * @param item {item} 物品
 * @param count {number} 符文槽数量
 * @returns {item}
 */
function toPerformedRuneWeapon(item, count) {
    let bore = '';// 孔
    for (let i = 0; i<2; i++) {
        bore += '§r§7「」';
    }
    let loreArray = item.getItemLore().split("§r§4§l一一一一一一一一一一;");
    loreArray[3] = '§l§b符文➪'+bore+';'+loreArray[3];
    return item;
}